Jawaban StackOverflow dengan> 3.5K memilih fitur one-liner ini untuk ditugaskan ke DIR
direktori skrip bash saat ini:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
Saya bingung dengan tanda kutip ganda yang bersarang. Sejauh yang saya tahu, fragmen berikut dikutip ganda:
"$( cd "
"${BASH_SOURCE[0]}"
" && pwd )"
... dan segala sesuatu lainnya di sebelah kanan =
(yaitu $( dirname
dan )
) tidak dikutip. Dengan kata lain, saya berasumsi bahwa karakter ke-2, ke-4, dan ke-6 "
"menutup" karakter ke-1, ke-3, dan ke-5 "
.
Saya mengerti apa yang "${BASH_SOURCE[0]}"
dicapai tanda kutip ganda , tetapi apa tujuan dari dua pasang tanda kutip lainnya?
Sebaliknya, jika (dan skor suara tinggi), cuplikan di atas tidak benar, apa cara yang tepat untuk mencapai maksud nominalnya?
( Maksud saya maksud: mengumpulkan nilai yang dikembalikan oleh pwd
setelah pertama- cd
ke direktori dikembalikan oleh dirname "${BASH_SOURCE[0]}"
, dan melakukan cd
-ing dalam sub-shell, sehingga $PWD
shell induk tetap tidak berubah).
$( here, it's a subshell, but you are writing code as if you were writing it on the "first level" of the shell .... )
.lsb_dist="$(. /etc/os-release && echo "$ID")"; echo "$lsb_dist"
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
berfungsi juga.Jawaban:
Teka-teki Anda tidak benar tentang bagaimana
bash
(dan shell secara umum) menguraikan input. Di:Pertama,
bash
parsing sisi kanan penugasan ke satu string panjang$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
karena kutipan ganda dapat muncul di dalam tanda kutip ganda .Setelah itu,
bash
mulai parsing substitusi perintah. Karena semua karakter berikut tanda kurung terbuka untuk melampirkan tanda kurung digunakan untuk membangun perintah di dalam substitusi perintah, Anda akan mendapatkan:Shell terus menguraikan perintah majemuk itu, memecahnya menjadi dua bagian:
cd "$( dirname "${BASH_SOURCE[0]}" )"
Kemudian menerapkan aturan penguraian yang sama untuk
cd "$( dirname "${BASH_SOURCE[0]}" )"
, tapi kali ini, tanda kutip ganda tidak berlebihan, tetapi masuk akal. Mereka mencegah pemisahan bidang pada hasil$( dirname "${BASH_SOURCE[0]}" )
, dan juga perluasan${BASH_SOURCE[0]}
(Berbeda dengan tanda kutip paling luar, tidak akan diperlukan dalam RHS penugasan variabel untuk mencegahsplit+glob
).Aturan ini berlaku untuk substitusi perintah di semua shell POSIX . Teka-teki lebih detail dapat Anda baca di bagian Pengakuan Token dari spesifikasi POSIX .
sumber
Begitu ada di dalam
$(...)
, mengutip dimulai dari awal.Dengan kata lain,
"..."
dan$(...)
bisa bersarang dalam satu sama lain. Substitusi proses$(...)
,, dapat berisi satu atau lebih string double-quote lengkap . Juga, string yang dikutip ganda dapat berisi satu atau lebih proses penggantian yang lengkap . Tapi, mereka tidak jalin. Dengan demikian, string yang dikutip ganda yang dimulai di dalam substitusi proses tidak akan pernah diperluas di luarnya atau sebaliknya.Jadi, pertimbangkan:
Di dalam batin
$(...)
adalah:Di atas
${BASH_SOURCE[0]}
adalah kutipan ganda. Setiap kutipan, ganda atau tunggal, di luar$(...)
tidak relevan ketika menentukan yang${BASH_SOURCE[0]}
dikutip ganda.Bagian luar
$(...)
berisi:Di sini, ungkapannya
$( dirname "${BASH_SOURCE[0]}" )
dikutip ganda. Fakta bahwa ada kutipan di luar luar$(...)
tidak relevan ketika mempertimbangkan apa yang ada di dalamnya. Fakta bahwa ada kutipan di dalam batin$(...)
juga tidak relevan.Berikut cara mencocokkan penawaran ganda:
sumber
irrelevant
? Kecuali sebagian besar kurung luar, semua yang lain memiliki makna sendiri.$(...)
mengikat lebih ketat dari"..."
" tidak masuk akal. Mereka bukan operator infiks, dan tidak ada hierarki di antara mereka (jika ada maka itu berarti bahwa kutipan tidak boleh di dalam tanda kurung atau tanda kurung tidak bisa di dalam tanda kutip, tapi bukan itu masalahnya). Istilah teknisnya adalah itu$(…)
dan"…"
sarang.