Saya seorang noob di shell-scripting. Saya ingin mencetak pesan dan keluar dari skrip saya jika ada perintah yang gagal. Saya sudah mencoba:
my_command && (echo 'my_command failed; exit)
tetapi tidak berhasil. Itu terus menjalankan instruksi mengikuti baris ini dalam skrip. Saya menggunakan Ubuntu dan bash.
linux
bash
exit
exitstatus
pengguna459246
sumber
sumber
Jawaban:
Mencoba:
Empat perubahan:
&&
ke||
{ }
di tempat( )
;
setelahexit
dan{
dan sebelumnya}
Karena Anda ingin mencetak pesan dan keluar hanya ketika perintah gagal (keluar dengan nilai bukan nol), Anda memerlukan
||
bukan&&
.akan berjalan
cmd2
ketikacmd1
berhasil (nilai keluar0
). Dimana sebagaiakan berjalan
cmd2
ketikacmd1
gagal (nilai keluar bukan nol).Menggunakan
( )
membuat perintah di dalamnya berjalan di sub-shell dan memanggilexit
dari sana menyebabkan Anda keluar dari sub-shell dan bukan shell asli Anda, maka eksekusi berlanjut di shell asli Anda.Untuk mengatasi ini gunakan
{ }
Dua perubahan terakhir diperlukan oleh bash.
sumber
{ (>&2 echo 'my_command failed') ; exit 1; }
Jawaban lain telah mencakup pertanyaan langsung dengan baik, tetapi Anda mungkin juga tertarik untuk menggunakannya
set -e
. Dengan itu, perintah apa pun yang gagal (di luar konteks tertentu sepertiif
tes) akan menyebabkan skrip dibatalkan. Untuk skrip tertentu, ini sangat berguna.sumber
set -e
memiliki seperangkat aturan yang panjang dan misterius tentang kapan ia bekerja dan kapan tidak. (Jika ada yang menjalankanif yourfunction; then ...
, makaset -e
tidak akan pernah menembak ke dalamyourfunction
atau apa pun yang dipanggil, karena kode itu dianggap "dicentang"). Lihat bagian latihan BashFAQ # 105 , membahas ini dan jebakan lainnya (beberapa di antaranya hanya berlaku untuk versi shell tertentu, jadi Anda harus memastikan untuk menguji setiap rilis yang mungkin digunakan untuk menjalankan skrip Anda).Perhatikan juga, status keluar setiap perintah disimpan dalam variabel shell $ ?, yang dapat Anda periksa segera setelah menjalankan perintah. Status bukan nol menunjukkan kegagalan:
sumber
echo "Just finished step A"
, tidak tahu bahwa ituecho
menimpa$?
yang akan diperiksa nanti.Jika Anda menginginkan perilaku itu untuk semua perintah dalam skrip Anda, tambahkan saja
di awal skrip. Sepasang opsi ini memberi tahu juru bahasa untuk keluar kapan pun perintah kembali dengan kode keluar yang tidak nol.
Ini tidak memungkinkan Anda untuk mencetak pesan keluar.
sumber
trap
bash built-in.set -o pipefail
mungkin bukan perilaku yang diinginkan. Masih terima kasih telah menunjukkannya!set -e
sama sekali tidak dapat diandalkan, konsisten atau dapat diprediksi! Untuk meyakinkan diri sendiri tentang hal itu, tinjau bagian latihan BashFAQ # 105 , atau tabel yang membandingkan perilaku kerang yang berbeda di in-ulm.de/~mascheck/various/set-eSaya telah meretas idiom berikut:
Awali setiap perintah dengan gema informatif, dan ikuti setiap perintah dengan
if [ $? -ne 0 ];...
baris yang sama . (Tentu saja, Anda dapat mengedit pesan kesalahan itu jika Anda mau.)sumber
if ! javac *.java; then ...
- Kenapa repot-repot$?
sama sekali?Asalkan
my_command
dirancang secara kanonik, yaitu mengembalikan 0 ketika berhasil, maka&&
kebalikan dari yang Anda inginkan. Kamu ingin||
.Perhatikan juga bahwa
(
tampaknya tidak benar bagi saya di bash, tetapi saya tidak dapat mencoba dari tempat saya berada. Katakan padaku.sumber
Anda juga dapat menggunakan, jika Anda ingin mempertahankan status kesalahan keluar, dan memiliki file yang dapat dibaca dengan satu perintah per baris:
Namun, ini tidak akan mencetak pesan kesalahan tambahan. Namun dalam beberapa kasus, kesalahan akan dicetak oleh perintah yang gagal.
sumber
exit $?
; hanyaexit
menggunakan$?
sebagai nilai standarnya.The
trap
shell builtin memungkinkan sinyal penangkapan, dan kondisi lain yang berguna, termasuk gagal eksekusi perintah (yaitu, status tidak nol). Jadi, jika Anda tidak ingin menguji status pengembalian setiap perintah secara eksplisit, Anda dapat mengatakantrap "your shell code" ERR
dan kode shell akan dieksekusi kapan saja perintah mengembalikan status tidak nol. Sebagai contoh:trap "echo script failed; exit 1" ERR
Perhatikan bahwa seperti halnya dengan kasus-kasus lain menangkap perintah yang gagal, pipa membutuhkan perawatan khusus; di atas tidak akan menangkap
false | true
.sumber