Saya melihat perilaku yang sama untuk loop di bawah ini sebagai loop dengan while [ 1 ]
. Kenapa begitu?
while [ 0 ]; do
echo "hello"
done
Saya melihat perilaku yang sama untuk loop di bawah ini sebagai loop dengan while [ 1 ]
. Kenapa begitu?
while [ 0 ]; do
echo "hello"
done
Jawaban:
Kurung kotak tunggal dalam shell adalah sinonim untuk test
(baik perintah terpisah atau built-in shell), jadi [ 0 ]
artinya sama dengan test 0
. test
adalah untuk melakukan perbandingan dan menguji atribut file, seperti yang dapat Anda baca di halaman manualnya. Ketika tidak diberi ekspresi yang terlihat seperti perbandingan, uji file, atau salah satu operasi lain yang bisa dilakukan, itu akan menguji apakah argumen ada dan string yang tidak kosong. Baik 0
atau 1
benar-benar input yang tepat untuk pengujian, dan sebagai tes string non-kosong hanya berhasil dan loop sementara Anda loop selamanya.
Anda mungkin ingin mencoba saja
while false; do
echo "hello"
done
mungkin diganti false
dengan true
. Atau mungkin yang Anda inginkan adalah menggunakan (( ))
:
while (( 0 )); do
echo "hello"
done
Yang akan berperilaku seperti kebanyakan bahasa, di mana 0 berarti gagal / salah dan 1 berarti sukses / benar.
0
dan 1
bukan string kosong. Pemrogram shell baru sering menulis if [ 1=2 ]
alih-alih if [ 1 = 2 ]
dan bertanya-tanya mengapa yang pertama selalu benar. Itu benar karena itu adalah argumen tunggal dan bukan string kosong.
Nilai 0 di sini tidak bertindak sebagai konstanta numerik, tetapi sebagai string karakter. Semua tes ini setara dalam efeknya menghasilkan status terminasi yang sukses:
[ A ]
[ "XYZ" ]
[ 0 ]
ini menghasilkan status pemutusan yang gagal:
[ ]
[ "" ]
ada argumen non-kosong, yang mengevaluasi ke true logis. Ini memungkinkan Anda melakukan hal-hal seperti:
if [ $UNDER_NUCLEAR_ATTACK ] ; then
launch-missiles -a $DRY_RUN # $DRY_RUN set to "-n" during testing
fi
Variabel UNDER_NUCLEAR_ATTACK
diatur ke nilai non-kosong untuk menunjukkan benar, atau tidak disetel atau kosong untuk menunjukkan salah.
Kita dapat menerapkan !
operator untuk membalik logika:
[ ! a ] # fails: a is nonblank so true; and not true is false.
[ ! ] # succeeds: blank is false, not blank is true.
Untuk mengevaluasi kondisi numerik, Anda harus menggunakan operator tes numerik:
while [ $A -gt $B ] ; do ...
Jika A
dan B
berisi string yang terlihat seperti bilangan bulat desimal, mereka dibandingkan seperti angka, dan jika A
lebih besar dari B
, loop dijalankan. Jadi anggaplah itu UNDER_NUCLEAR_ATTACK
bukan boolean tipe string yang kosong atau tidak kosong, tetapi sebenarnya boolean numerik yang baik 0
(salah) atau beberapa nilai lainnya (benar). Dalam hal ini, kami akan menulis tes seperti ini:
if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...
Jika / kemudian membangun tes apakah status keluar dari daftar perintah adalah 0 (karena 0 berarti "sukses" oleh konvensi UNIX), dan jika demikian, jalankan satu atau lebih perintah.
Singkatnya, Anda mengembalikan hasil tes nol.
[
hanya mendapat satu argumen (tidak termasuk ]
, tentu saja) itu keluar dengan status nol jika argumen tidak kosong, tidak nol jika itu. Jadi, misalnya, [ 1 ]
juga akan mengembalikan kode keluar dari 0
.
Nilai 0 dianggap sebagai true untuk loop sementara karena itu kondisi untuk loop sementara benar dan karena itu terus menerus untuk menunjukkan loop tak terbatas. Benar jika kita mengganti 0 dengan 1, karena setiap bilangan bulat yang kita tulis di antara kondisi itu akan mengembalikan true
[ ]
(tanpa argumen) dan[ "" ]
(dengan argumen kosong tunggal) tidak berhasil.