Saya belajar tentang struktur pengambilan keputusan dan saya menemukan kode-kode ini:
if [ -f ./myfile ]
then
cat ./myfile
else
cat /home/user/myfile
fi
[ -f ./myfile ] &&
cat ./myfile ||
cat /home/user/myfile
Keduanya berperilaku sama. Apakah ada keuntungan menggunakan satu arah dari yang lain?
shell-script
syntax
control-flow
Subhaa Chandar
sumber
sumber
Jawaban:
Tidak, konstruksi
if A; then B; else C; fi
danA && B || C
yang tidak setara .Dengan
if A; then B; else C; fi
, perintahA
selalu dievaluasi dan dieksekusi (setidaknya upaya untuk mengeksekusi dibuat) dan kemudian perintahB
atau perintahC
dievaluasi dan dieksekusi.Dengan
A && B || C
, itu sama untuk perintahA
danB
tetapi berbeda untukC
: perintahC
dievaluasi dan dijalankan jika baikA
gagal atauB
gagal.Dalam contoh Anda, anggaplah Anda
chmod u-r ./myfile
, maka, meskipun[ -f ./myfile ]
berhasil, Anda akan melakukannyacat /home/user/myfile
Saran saya: gunakan
A && B
atauA || B
semua yang Anda inginkan, ini tetap mudah dibaca dan dipahami dan tidak ada jebakan. Tetapi jika Anda maksud jika ... maka ... lain ... kemudian gunakanif A; then B; else C; fi
.sumber
Kebanyakan orang merasa lebih mudah untuk memahami
if
...then
...else
...fi
bentuk.Untuk itu
a && b || c
, Anda harus memastikan bahwab
mengembalikan true. Ini adalah penyebab bug halus dan merupakan alasan bagus untuk menghindari gaya ini. Jika b tidak mengembalikan true, ini tidak sama.Untuk pengujian dan tindakan yang sangat singkat yang tidak memiliki klausa lain, panjang yang pendek itu menarik, misalnya
&&
dan||
yangshort circuiting operators
, segera setelah hasilnya diketahui tes yang tidak dibutuhkan lanjut yang dilewati.a && b || c
dikelompokkan sebagai(a && b) || c
. Pertamaa
dijalankan. Jika itufails
yang didefinisikan sebagai tidak mengembalikan status keluar dari 0, maka grup(a && b)
diketahuifail
danb
tidak perlu dijalankan. Tidak||
tahu hasil dari ekspresi sehingga perlu dieksekusic
. Jikaa
berhasil (mengembalikan nol) maka&&
operator belum mengetahui hasila && b
sehingga harus larib
untuk mencari tahu. Jikab
berhasil makaa && b
berhasil dan yang||
tahu hasil keseluruhan adalah sukses, jadi tidak perlu dijalankanc
. Jikab
gagal maka||
masih belum tahu nilai ekspresi, jadi perlu dijalankanc
.sumber
Operator && menjalankan perintah berikutnya jika perintah sebelumnya berhasil, (kode keluar yang dikembalikan ($?) 0 = logis benar).
Dalam bentuk
A && B || C
, perintah (atau kondisi) A dievaluasi dan jika A mengembalikan true (sukses, keluar kode 0) maka perintah B dijalankan. Jika A gagal (dengan demikian akan mengembalikan kode keluar - palsu selain 0) dan / atau B gagal (kembali salah ) maka perintah C akan dieksekusi.Juga
&&
operator digunakan sebagai DAN dalam kondisi cek dan operator||
bekerja seperti ATAU dalam kondisi cek.Bergantung pada apa yang ingin Anda lakukan dengan skrip Anda, formulir
A && B || C
dapat digunakan untuk pemeriksaan kondisi seperti contoh Anda atau dapat digunakan untuk rantai perintah dan memastikan serangkaian perintah yang akan dieksekusi jika perintah sebelumnya memiliki kode keluar 0 yang berhasil .Inilah sebabnya mengapa itu adalah umum untuk melihat perintah seperti:
do_something && do_something_else_that_depended_on_something
.Contoh:
apt-get update && apt-get upgrade
Jika pembaruan gagal maka pemutakhiran tidak dilakukan, (masuk akal di dunia nyata ...).mkdir test && echo "Something" > test/file
Bagian
echo "Something"
akan dieksekusi hanya jikamkdir test
berhasil dan operasi mengembalikan kode keluar 0 ../configure --prefix=/usr && make && sudo make install
Biasanya ditemukan pada kompilasi pekerjaan untuk menghubungkan perintah yang diperlukan secara bersamaan.
Jika Anda mencoba menerapkan "rantai" di atas dengan if - then - else Anda akan membutuhkan lebih banyak perintah dan pemeriksaan (dan dengan demikian lebih banyak kode untuk ditulis - lebih banyak hal yang salah) untuk tugas yang sederhana.
Juga, ingatlah bahwa perintah berantai dengan && dan || dibaca oleh shell dari kiri ke kanan. Anda mungkin perlu mengelompokkan perintah dan memeriksa kondisi dengan tanda kurung untuk bergantung pada langkah berikutnya pada keluaran yang berhasil dari beberapa perintah sebelumnya. Sebagai contoh lihat ini:
Atau contoh kehidupan nyata:
Perlu diingat bahwa beberapa perintah mengembalikan kode keluar yang berbeda tergantung pada proses yang dijalankan, atau mengembalikan kode yang berbeda tergantung pada tindakan mereka, (misalnya perintah GNU
diff
, mengembalikan 1 jika dua file berbeda, dan 0 jika tidak). Perintah semacam itu perlu diperlakukan dengan hati-hati di && dan || .Juga hanya untuk memiliki semua teka-teki bersama, pikirkan gabungan perintah menggunakan
;
operator. Dengan formatA;B;C
semua perintah akan dieksekusi secara seri tidak peduli apa kode keluar dari perintahA
danB
.sumber
Banyak kebingungan tentang hal ini mungkin disebabkan oleh dokumentasi bash yang memanggil daftar AND dan OR ini . Meskipun secara logika mirip dengan
&&
dan||
ditemukan di dalam kurung siku, fungsinya berbeda.Beberapa contoh dapat menggambarkan hal terbaik ini ...
Jika
cmda
keluar benar,cmdb
dieksekusi.Jika
cmda
keluar salah,cmdb
TIDAK dijalankan, tetapicmdc
.Bagaimana
cmda
jalan keluar diabaikan.Jika
cmdb
keluar benar,cmdc
dieksekusi.Jika
cmdb
keluar salah,cmdc
TIDAK dijalankan dancmdd
tidak.Jika
cmda
keluar benar,cmdb
dijalankan, diikuti olehcmdc
.Jika
cmda
keluar salah,cmdb
TIDAK dijalankan tetapicmdc
sedang.Hah? Kenapa
cmdc
dieksekusi?Karena bagi penerjemah, tanda titik koma (
;
) dan baris baru memiliki arti yang persis sama. Bash melihat baris kode itu sebagai ...Untuk mencapai apa yang diharapkan, kita harus menyertakan
cmdb; cmdc
kurung kurawal di dalam untuk menjadikannya Perintah Kompon (perintah grup) . Titik koma penghentian tambahan hanyalah persyaratan{ ...; }
sintaksis. Jadi kita dapatkan ...cmda && { cmdb; cmdc; }
Jika
cmda
keluar benar,cmdb
dijalankan, diikuti olehcmdc
.Jika
cmda
keluar salah, tidak adacmdb
ataucmdc
dieksekusi.Eksekusi berlanjut dengan baris berikutnya.
Pemakaian
Daftar perintah bersyarat paling berguna untuk mengembalikan sesegera mungkin dari fungsi dan dengan demikian menghindari menafsirkan dan mengeksekusi banyak kode yang tidak perlu. Meskipun demikian, beberapa fungsi kembali, bahwa seseorang harus menjadi obsesif tentang menjaga fungsi tetap pendek sehingga lebih mudah untuk memastikan bahwa semua kondisi yang mungkin tercakup.
Ini adalah contoh dari beberapa kode yang sedang berjalan ...
sumber