Saya memiliki skrip Bash shell yang memanggil sejumlah perintah. Saya ingin agar skrip shell secara otomatis keluar dengan nilai kembali 1 jika ada perintah yang mengembalikan nilai bukan nol.
Apakah ini mungkin tanpa secara eksplisit memeriksa hasil dari setiap perintah?
misalnya
dosomething1
if [[ $? -ne 0 ]]; then
exit 1
fi
dosomething2
if [[ $? -ne 0 ]]; then
exit 1
fi
set -e
, lakukan jugaset -u
(atauset -eu
).-u
mengakhiri perilaku idiot, penyembunyian bug yang Anda dapat mengakses variabel tidak ada dan memiliki nilai kosong yang dihasilkan tanpa diagnostik.Jawaban:
Tambahkan ini ke awal skrip:
Ini akan menyebabkan shell keluar segera jika perintah sederhana keluar dengan nilai keluar yang bukan nol. Perintah sederhana adalah perintah apa pun yang bukan bagian dari jika, sementara, atau sampai pengujian, atau bagian dari && atau || daftar.
Lihat halaman manual bash (1) pada perintah internal "set" untuk lebih jelasnya.
Saya pribadi memulai hampir semua skrip shell dengan "set -e". Sangat menjengkelkan untuk memiliki skrip yang terus berlanjut ketika sesuatu gagal di tengah dan mematahkan asumsi untuk sisa skrip.
sumber
bash script.sh
.set -e; tf() { false; }; tf; echo 'still here'
. Bahkan tanpaset -e
di dalam tubuhtf()
, eksekusi dibatalkan. Mungkin Anda bermaksud mengatakan bahwaset -e
itu tidak diwarisi oleh subkulit , yang benar.Untuk menambah jawaban yang diterima:
Camkan itu
set -e
kadang kadang tidak cukup, khususnya jika Anda memiliki pipa.Misalnya, Anda memiliki skrip ini
... yang berfungsi seperti yang diharapkan: kesalahan dalam
configure
membatalkan eksekusi.Besok Anda membuat perubahan yang tampaknya sepele:
... dan sekarang tidak berfungsi. Ini dijelaskan di sini , dan solusi (hanya Bash) disediakan:
sumber
pipefail
ikutset -o
!Pernyataan if dalam contoh Anda tidak perlu. Lakukan saja seperti ini:
Jika Anda mengikuti saran Ville Laurikari dan menggunakannya
set -e
untuk beberapa perintah, Anda mungkin perlu menggunakan ini:The
|| true
akan membuat pipa perintah memilikitrue
nilai kembali bahkan jika perintah gagal sehingga para-e
opsi tidak akan membunuh script.sumber
set -e
bukan bash-centric - itu didukung bahkan pada Shell Bourne asli.Jika Anda memiliki pembersihan yang harus Anda lakukan saat keluar, Anda juga dapat menggunakan 'jebakan' dengan ERR sinyal semu. Ini bekerja dengan cara yang sama seperti menjebak INT atau sinyal lainnya; bash melempar ERR jika ada perintah yang keluar dengan nilai bukan nol:
Atau, terutama jika Anda menggunakan "set -e", Anda bisa menjebak EXIT; perangkap Anda kemudian akan dieksekusi ketika skrip keluar karena alasan apa pun, termasuk akhir yang normal, interupsi, jalan keluar yang disebabkan oleh opsi -e, dll.
sumber
The
$?
variabel jarang diperlukan. Idi semucommand; if [ $? -eq 0 ]; then X; fi
harus selalu ditulis sebagaiif command; then X; fi
.Kasus-kasus di mana
$?
diperlukan adalah ketika itu perlu diperiksa terhadap beberapa nilai:atau ketika
$?
perlu digunakan kembali atau dimanipulasi:sumber
Jalankan dengan
-e
atauset -e
di atas.Lihat juga
set -u
.sumber
help set
:-u
memperlakukan referensi untuk menghapus variabel sebagai kesalahan.set -u
atauset -e
tidak keduanya? @lumpynoseEkspresi suka
akan berhenti memproses ketika salah satu perintah kembali dengan nilai yang tidak nol. Misalnya, perintah berikut tidak akan pernah mencetak "selesai":
sumber
harus cukup.
sumber
hanya melemparkan satu lagi untuk referensi karena ada pertanyaan tambahan untuk input Mark Edgars dan berikut adalah contoh tambahan dan menyentuh topik secara keseluruhan:
yang sama dengan yang
cmd || exit errcode
ditunjukkan seseorang.misalnya. Saya ingin memastikan partisi dilepas jika dipasang:
sumber
[[
cmd`]] `bukan hal yang sama. Itu salah jika output perintah kosong dan benar sebaliknya, terlepas dari status keluar perintah.