Saya pikir rekomendasi yang Anda lihat adalah untuk POSIX sh dan / atau testperintah yang berfungsi sebagai [perintah, daripada [[konstruk yang muncul di ksh (terima kasih Stéphane Chazelas untuk tipnya) dan juga digunakan misalnya dalam bash, zsh dan beberapa lainnya kerang.
Dalam sebagian besar bahasa, seperti C, ketika klausa sudah diketahui benar atau salah, tidak perlu mengevaluasi bagian-bagian sisanya tergantung pada operasi: jika benar bukan setelah logis atau mengikutinya, jika salah bukan setelah logis dan , dll. Ini tentu saja memungkinkan misalnya untuk berhenti ketika pointer NULL dan tidak mencoba untuk men-dereference-kannya pada klausa berikutnya.
Tapi sh 's [ expr1 -o expr2 ]konstruk (termasuk implementasi bash) tidak melakukan hal ini: selalu mengevaluasi kedua belah pihak, ketika salah satu ingin hanya expr1 untuk dievaluasi. Ini mungkin dilakukan untuk kompatibilitas dengan testimplementasi perintah. Di sisi lain, sh ||dan &&ikuti prinsip yang biasa: tidak dievaluasi jika tidak akan mengubah hasilnya.
Jadi perbedaan yang perlu diperhatikan adalah:
: > /tmp/effect #clear effect
if [ 1 -eq 1 -o $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]; then
echo true;
fi
cat /tmp/effect
yang menghasilkan:
true
or-was-evaluated
Di atas, masing [- masing bisa diganti dengan /usr/bin/[yang merupakan alias untuk testperintah, digunakan sebelum [dibuat built-in ke shell.
Sementara dua konstruksi berikutnya:
: > /tmp/effect #clear effect
if [ 1 -eq 1 ] || [ $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]; then
echo true;
fi
cat /tmp/effect
atau
: > /tmp/effect #clear effect
if [[ 1 -eq 1 || $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]]; then
echo true;
fi
cat /tmp/effect
Hanya akan menghasilkan truedan membiarkan effectkosong: ||berperilaku dengan benar, dan [[memperbaiki masalah ini juga.
MEMPERBARUI:
Ketika @ StéphaneChazelas berkomentar, saya melewatkan beberapa perbedaan terkait dengan pertanyaan awal. Saya hanya akan menempatkan di sini yang paling penting (setidaknya bagi saya): prioritas operator.
Sementara shell tidak akan mempertimbangkan prioritas:
if true || true && false; then
echo true
else
echo false
fi
hasil (karena tidak ada prioritas dan dengan demikian pertama true || truedievaluasi, dan kemudian && false):
false
di [[ ]]dalam &&operator lebih diutamakan daripada ||:
if [[ 1 -eq 1 || 1 -eq 1 && 1 -eq 0 ]]; then
echo true
else
echo false
fi
hasil (karena 1 -eq 1 && 1 -eq 0dikelompokkan dan dengan demikian anggota ke-2 ||):
true
setidaknya untuk ksh , bash , zsh .
Jadi [[ ]]telah meningkatkan perilaku baik dari [ ]operator shell langsung dan logis.
[atautest( tidak[[), cariOBtag (tertaut ke definisi "usang") dalam spesifikasi POSIX untuktest. Dalamtest, ada beberapa kasus patologis di mana tidak mungkin untuk mengetahui apakah(atau)dimaksudkan untuk menjadi sintaks yang berarti untuk perintah pengujian atau string yang akan diuji, sehingga orang yang mengabaikan penanda keusangan dan menggunakan sintaksis itu sebenarnya dapat membutuhkan sebaliknya."x$foo"praktik usang ; dengan[[, itu bukan masalah.