Di lingkungan Bash saya, saya menggunakan variabel yang mengandung spasi, dan saya menggunakan variabel ini dalam substitusi perintah.
Apa cara yang benar untuk mengutip variabel saya? Dan bagaimana saya harus melakukannya jika ini bersarang?
DIRNAME=$(dirname "$FILE")
atau apakah saya mengutip di luar substitusi?
DIRNAME="$(dirname $FILE)"
atau keduanya?
DIRNAME="$(dirname "$FILE")"
atau apakah saya menggunakan tanda centang kembali?
DIRNAME=`dirname "$FILE"`
Apa cara yang tepat untuk melakukan ini? Dan bagaimana saya dapat dengan mudah memeriksa apakah tanda kutip sudah disetel dengan benar?
Jawaban yang Diterima:
Urutan dari yang terburuk ke yang terbaik:
DIRNAME="$(dirname $FILE)"
tidak akan melakukan apa yang Anda inginkan jika$FILE
berisi spasi (atau karakter apa pun$IFS
saat ini berisi) atau karakter globbing[?*
.DIRNAME=`dirname "$FILE"`
secara teknis benar, tetapi backtick tidak direkomendasikan untuk perluasan perintah karena kerumitan ekstra saat menyarangkannya dan pemrosesan backslash ekstra yang terjadi di dalamnya.DIRNAME=$(dirname "$FILE")
benar, tetapi hanya karena ini adalah penugasan ke variabel skalar (bukan array). Jika Anda menggunakan substitusi perintah dalam konteks lain, sepertiexport DIRNAME=$(dirname "$FILE")
ataudu $(dirname -- "$FILE")
, kurangnya tanda kutip akan menyebabkan masalah jika hasil perluasan mengandung karakter spasi putih atau globbing.DIRNAME="$(dirname "$FILE")"
(kecuali untuk--
. yang hilang , lihat di bawah) adalah cara yang disarankan. Anda dapat menggantiDIRNAME=
dengan perintah dan spasi tanpa mengubah apa pun, dandirname
menerima string yang benar.
Untuk meningkatkan lebih jauh lagi:
DIRNAME="$(dirname -- "$FILE")"
bekerja jika$FILE
dimulai dengan tanda hubung.DIRNAME="$(dirname -- "$FILE" && printf x)" && DIRNAME="${DIRNAME%?x}" || exit
bekerja bahkan jika$FILE
dirname diakhiri dengan baris baru, karena$()
memotong baris baru di akhir output, keduanya ditambahkan olehdirname
dan yang mungkin merupakan bagian dari data sebenarnya.
Anda dapat membuat sarang ekspansi perintah sebanyak yang Anda suka. Dengan $()
Anda selalu membuat konteks kutipan baru, sehingga Anda dapat melakukan hal-hal seperti ini:
foo "$(bar "$(baz "$(ban "bla")")")"
Anda tidak ingin mencobanya dengan backticks.