Bagaimana saya mendapatkan hanya nama direktori kerja saat ini dalam skrip bash, atau bahkan lebih baik, hanya perintah terminal.
pwdmemberikan path lengkap dari direktori kerja saat ini, misalnya /opt/local/bintetapi saya hanya inginbin
Bagaimana saya mendapatkan hanya nama direktori kerja saat ini dalam skrip bash, atau bahkan lebih baik, hanya perintah terminal.
pwdmemberikan path lengkap dari direktori kerja saat ini, misalnya /opt/local/bintetapi saya hanya inginbin
Jawaban:
Tidak perlu basename, dan terutama tidak perlu untuk menjalankan pwd subkulit (yang menambahkan operasi garpu tambahan, dan mahal ); shell dapat melakukan ini secara internal menggunakan ekspansi parameter :
result=${PWD##*/} # to assign to a variable
printf '%s\n' "${PWD##*/}" # to print to stdout
# ...more robust than echo for unusual names
# (consider a directory named -e or -n)
printf '%q\n' "${PWD##*/}" # to print to stdout, quoted for use as shell input
# ...useful to make hidden characters readable.
Perhatikan bahwa jika Anda menerapkan teknik ini dalam keadaan lain (tidak PWD, tetapi beberapa variabel lain yang memegang nama direktori), Anda mungkin perlu memotong garis miring apa pun. Di bawah ini menggunakan dukungan extglob bash untuk bekerja bahkan dengan beberapa garis miring:
dirname=/path/to/somewhere//
shopt -s extglob # enable +(...) glob syntax
result=${dirname%%+(/)} # trim however many trailing slashes exist
result=${result##*/} # remove everything before the last / that still remains
printf '%s\n' "$result"
Atau, tanpa extglob:
dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}" # remove everything before the last /
$PWDadalah nama variabel bash bawaan ; semua nama variabel bawaan ada dalam huruf kapital semua (untuk membedakannya dari variabel lokal, yang harus selalu memiliki setidaknya satu karakter huruf kecil). result=${PWD#*/}tidak tidak mengevaluasi /full/path/to/directory; alih-alih, itu hanya menghapus elemen pertama, membuatnya path/to/directory; menggunakan dua #karakter membuat pola cocok serakah, serasi karakter sebanyak mungkin. Baca halaman ekspansi parameter, ditautkan dalam jawaban, untuk lebih lanjut.
pwdtidak selalu sama dengan nilai $PWD, karena komplikasi yang timbul dari cdtautan simbolik, apakah bash memiliki -o physicalopsi yang disetel, dan sebagainya. Ini digunakan untuk menjadi sangat tidak enak di sekitar penanganan direktori automounted, di mana merekam jalur fisik bukannya yang logis akan menghasilkan jalur yang, jika digunakan, akan memungkinkan automounter untuk secara spontan menurunkan direktori yang digunakan.
shdan cshdan jika Anda ingin kunci backspace bekerja Anda harus membaca sttyhalaman manual keseluruhan , dan kami menyukainya!"
Gunakan basenameprogramnya. Untuk kasus Anda:
% basename "$PWD"
bin
basenameprogram ini? Apa yang salah dengan jawaban ini selain melewatkan tanda kutip?
basenamememang program eksternal yang melakukan hal yang benar, tetapi menjalankan setiap program eksternal untuk hal pesta dapat melakukan out-of-the-box dengan hanya menggunakan built-in fungsi konyol, menimbulkan dampak kinerja ( fork(), execve(), wait(), dll) untuk tak ada alasan.
basenamesini tidak berlaku dirname, karena dirnamememiliki fungsi yang ${PWD##*/}tidak - mengubah string tanpa garis miring ., misalnya. Jadi, sementara menggunakan dirnamesebagai alat eksternal memiliki overhead kinerja, itu juga memiliki fungsi yang membantu untuk mengkompensasi yang sama.
functionKata kuncinya adalah POSIX-tidak cocok tanpa menambahkan nilai apa pun atas sintaks standar, dan kurangnya tanda kutip akan membuat bug dalam nama direktori dengan spasi. wdexec() { "./$(basename "$PWD")"; }mungkin menjadi alternatif yang lebih disukai.
basenamekurang "efisien". Tapi itu mungkin lebih efisien dalam hal produktivitas pengembang karena mudah diingat dibandingkan dengan sintaksis jelek. Jadi, jika Anda mengingatnya, lakukanlah. Kalau tidak, basenameberfungsi juga. Adakah yang pernah harus meningkatkan "kinerja" skrip bash dan membuatnya lebih efisien?
$ echo "${PWD##*/}"
echo "${PWD##*/}".
name=${PWD##*/}akan benar, dan name=$(echo "${PWD##*/}")akan salah (dalam arti tidak perlu-inefisiensi).
Anda dapat menggunakan kombinasi pwd dan basename. Misalnya
#!/bin/bash
CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`
echo "$BASENAME"
exit;
Bagaimana dengan grep:
pwd | grep -o '[^/]*$'
pwd | xargs basenametidak .. mungkin tidak begitu penting tetapi jawaban lainnya lebih sederhana dan lebih konsisten di seluruh lingkungan
Saya suka jawaban yang dipilih (Charles Duffy), tetapi hati-hati jika Anda berada di direktori yang disinkronkan dan Anda ingin nama direktori target. Sayangnya saya tidak berpikir itu bisa dilakukan dalam ekspresi ekspansi parameter tunggal, mungkin saya salah. Ini seharusnya bekerja:
target_PWD=$(readlink -f .)
echo ${target_PWD##*/}
Untuk melihat ini, percobaan:
cd foo
ln -s . bar
echo ${PWD##*/}
melaporkan "bilah"
Untuk menampilkan direktori terkemuka dari sebuah path (tanpa mengeluarkan fork-exec dari / usr / bin / dirname):
echo ${target_PWD%/*}
Ini misalnya akan mengubah foo / bar / baz -> foo / bar
readlink -fini adalah ekstensi GNU, dan karenanya tidak tersedia pada BSD (termasuk OS X).
echo "$PWD" | sed 's!.*/!!'
Jika Anda menggunakan shell Bourne atau ${PWD##*/}tidak tersedia.
${PWD##*/}adalah POSIX sh - setiap modern / bin / sh (termasuk tanda hubung, abu, dll) mendukungnya; untuk menekan Bourne yang sebenarnya pada kotak baru-baru ini, Anda harus menggunakan sistem Solaris yang agak tua. Di luar itu - echo "$PWD"; meninggalkan tanda kutip menyebabkan bug (jika nama direktori memiliki spasi, karakter wildcard, dll).
Anehnya, tidak ada yang menyebutkan alternatif ini yang hanya menggunakan perintah bash bawaan:
i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"
Sebagai bonus tambahan, Anda dapat dengan mudah mendapatkan nama direktori induk dengan:
[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"
Ini akan bekerja pada Bash 4.3-alpha atau lebih baru.
Menggunakan:
basename "$PWD"
ATAU
IFS=/
var=($PWD)
echo ${var[-1]}
Ubah Internal Filename Separator (IFS) kembali ke ruang kosong.
IFS=
Ada satu ruang setelah IFS.
basename $(pwd)
atau
echo "$(basename $(pwd))"
pwdstring-split dan glob-diperluas sebelum diteruskan ke basename.
basename "$(pwd)"- meskipun itu sangat tidak efisien dibandingkan dengan adil basename "$PWD", yang dengan sendirinya tidak efisien dibandingkan dengan menggunakan ekspansi parameter alih-alih memanggil basenamesama sekali.
Untuk menemukan joki di luar sana seperti saya:
find $PWD -maxdepth 0 -printf "%f\n"
$PWDuntuk "$PWD"untuk secara benar menangani nama direktori yang tidak biasa.
Saya biasanya menggunakan ini dalam skrip sh
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder
Anda dapat menggunakan ini untuk mengotomatiskan hal-hal ...
Grep bawah dengan regex juga berfungsi,
>pwd | grep -o "\w*-*$"
Cukup gunakan:
pwd | xargs basename
atau
basename "`pwd`"
xargsFormultion tidak efisien dan bermasalah ketika nama direktori berisi baris baru atau karakter kutipan, dan formulasi kedua memanggil pwdperintah dalam subkulit, alih-alih mengambil hasil yang sama melalui ekspansi variabel bawaan.
Jika Anda hanya ingin melihat direktori saat ini di wilayah bash prompt, Anda dapat mengedit .bashrcfile di ~. Ubah \wke \Wdalam baris:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
Lari source ~/.bashrc dan itu hanya akan menampilkan nama direktori di wilayah prompt.
Ref: /superuser/60555/show-only-current-directory-name-not-full-path-on-bash-prompt
Saya sangat suka menggunakan gbasename, yang merupakan bagian dari GNU coreutils.
basenamesana. Ini biasanya dipanggil gbasenamepada MacOS dan platform lain yang jika tidak dikirimkan dengan nama pengguna non-GNU.
Perintah berikut ini akan menghasilkan pencetakan direktori kerja Anda saat ini dalam skrip bash.
pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR
$1akan berisi direktori kerja saat ini. (2) The pushddanpopd tidak ada gunanya di sini karena apa pun di dalam backticks dilakukan dalam subkulit - sehingga tidak dapat memengaruhi direktori induk shell untuk memulainya. (3) Menggunakan "$(cd "$1"; pwd)"akan lebih mudah dibaca dan tahan terhadap nama direktori dengan spasi.