Saya mendapatkan apa yang saya harapkan ketika melakukan ini di bash
:
[ "a" == "a" ] && echo yes
Itu memberi saya yes
.
Tetapi ketika saya melakukan ini zsh
, saya mendapatkan yang berikut:
zsh: = not found
Mengapa perintah yang sama ( /usr/bin/[
) berperilaku berbeda di shell yang berbeda?
$PATH
dicari. dan==
bukantest
sintaks yang valid untuk/usr/bin/[
anway. Baik=
-baik saja.Jawaban:
Itu tidak ada
/usr/bin/[
di salah satu kerang. Dalam Bash, Anda menggunakan built-intest
/[
perintah , dan sama di zsh .Perbedaannya adalah bahwa zsh juga memiliki
=
ekspansi :=foo
memperluas ke jalur kefoo
executable. Itu berarti==
diperlakukan sebagai berusaha untuk menemukan perintah yang disebut=
diPATH
. Karena perintah itu tidak ada, Anda mendapatkan kesalahanyang Anda lihat (dan pada kenyataannya, hal yang sama ini akan terjadi bahkan jika Anda benar-benar menggunakan
/usr/bin/[
).Anda dapat menggunakan di
==
sini jika Anda benar-benar menginginkannya. Ini berfungsi seperti yang Anda harapkan di zsh:karena kutipan mencegah
=word
ekspansi berjalan. Anda juga dapat menonaktifkanequals
opsi dengansetopt noequals
.Namun, Anda akan lebih baik:
=
, tes kesetaraan yang kompatibel dengan POSIX ; atau[[
kondisi dengan==
baik di Bash dan zsh . Secara umum,[[
lebih baik dan lebih aman di sekitar, termasuk menghindari masalah seperti ini (dan lainnya) dengan memiliki aturan penguraian khusus di dalam.sumber
[
dan[[
? (Pencarian di Google hanya[ vs [[
memberi saya hasilvs
, LOL)[[
mendukung serangkaian tes yang lebih luas dalam kedua kasus, dan memiliki aturan penguraian khusus yang menghindari perlunya mengutip variabel, operator, dan sebagainya. Jika Anda secara khusus menggunakan Bash atau zsh, gunakan[[
. Jika Anda menulis skrip portabel, tulis ke perintah[
/ kompatibel POSIXtest
(yang mungkin atau mungkin bukan perintah nyata pada sistem Anda yang sedang berjalan).[[
sana dan lupakan saja[
.[[
adalah berbeda mampu. coba ini dengan itu:for f in *; do [ -e "$f" ] && for a in f d h p S b c; do [ "-$a" "$f" ] && for p in r w x u g; do [ "-$p" "$f" ] || p=-; a=$a$p; done && break; done && printf "%s:\t%s\n" "$a" "$f"; done
.=
/==
ini bisa dibilang salah satu kasus di mana[[
tidak lebih baik dari[
, seperti[[ a == b ]]
yang dilakukannya "a" cocok dengan "b" pola dan tidak adalah "a" sama dengan "b" seperti yang Anda harapkan. Itu artinya Anda harus menulis[[ $a == "$b" ]]
misalnya. Setidaknya, dengan[
perintah, jika Anda tahu cara kerja parsing perintah, Anda tahu Anda harus menulisnya[ "$a" = "$b" ]
untuk mencegah operator split + glob seperti pada perintah lain. Dengan mengingat hal itu dan jika Anda tidak menggunakan -a atau -o,[
aman dalam implementasi POSIX yang sesuai.Dan zsh, dan bash memberikan jawaban yang sama (
type
juga dibangun untuk kedua shell):sumber
[
adalah perintah shell builtin di bash dan di zsh:Dari dokumentasi Perintah Shell Builtin :
Dokumentasi resmi (
$ help test
) hanya memungkinkan untuk menggunakan=
:Jadi, ungkapan yang benar adalah:
Apa yang terjadi adalah bahwa bash agak kurang ketat. Mendukung
==
operator dengan[
tampaknya merupakan ekstensi bash dan tidak disarankan untuk menggunakannya:Jika Anda ingin menggunakan
==
, Anda harus menggunakan[[
kata kunci:Ingatlah bahwa
[[
itu kurang portabel (bukan POSIX). Tapi bash dan zsh mendukungnya.sumber
Di kedua shell,
bash
danzsh
,[
utilitas adalah shell builtin. Ini adalah implementasi shell dari alat itu, digunakan sebagai preferensi terhadap biner/usr/bin/[
. Perbedaan hasil yang Anda temui disebabkan oleh implementasi yang berbeda.Di
bash
,[
utilitas menerimaCONDITIONAL EXPRESSIONS
sebagai[[
perintah majemuk. Menurut halaman manual bashs keduanya=
dan==
valid:Dalam
zsh
,[
utilitas mencoba untuk mengimplementasikan POSIX dan ekstensi-ekstensinya di tempat ini ditentukan. Dalam spesifikasi utilitas tes POSIX tidak ada==
operator yang ditentukan.sumber