Baru-baru ini saya menemukan daftar Kode Keluar Dengan Makna Khusus dari Panduan Script Bash Lanjutan. Mereka menyebut kode-kode ini sebagai cadangan dan merekomendasikan bahwa:
Menurut tabel di atas, kode keluar 1-2, 126-165, dan 255 memiliki makna khusus, dan karenanya harus dihindari untuk parameter keluar yang ditentukan pengguna.
Beberapa waktu yang lalu, saya menulis skrip yang menggunakan kode status keluar berikut:
- 0 - sukses
- 1 - nama host salah
- 2 - argumen yang tidak valid ditentukan
- 3 - hak pengguna tidak mencukupi
Ketika saya menulis skrip saya tidak mengetahui adanya kode keluar khusus jadi saya mulai saja pada 1 untuk kondisi kesalahan pertama, dan menambah status keluar untuk setiap jenis kesalahan berturut-turut.
Saya menulis skrip dengan maksud bahwa pada tahap selanjutnya dapat dipanggil oleh skrip lain (yang dapat memeriksa kode keluar yang tidak nol). Saya belum benar-benar melakukannya; sejauh ini saya hanya menjalankan skrip dari shell interaktif saya (Bash) dan saya bertanya-tanya apa / jika ada masalah yang disebabkan oleh penggunaan kode keluar khusus saya. Seberapa relevan / penting rekomendasi dari Panduan Advanced Bash-Scripting?
Saya tidak dapat menemukan saran yang menguatkan dalam dokumentasi Bash; bagiannya pada Status Keluar hanya mencantumkan kode keluar yang digunakan oleh Bash tetapi tidak menyatakan bahwa semua ini dicadangkan atau diperingatkan agar tidak menggunakannya untuk skrip / program Anda sendiri.
sumber
Jawaban:
Ada beberapa upaya untuk menstandarkan arti dari kode keluar proses. Selain yang Anda sebutkan, saya tahu:
BSD memiliki
sysexits.h
yang mendefinisikan makna untuk nilai dari 64 ke atas.grep
Dokumen GNU yang keluar kode 0 berarti setidaknya satu kecocokan ditemukan, 1 berarti tidak ada kecocokan yang ditemukan, dan 2 berarti kesalahan I / O terjadi; konvensi ini jelas juga berguna untuk program lain yang perbedaan antara "tidak ada yang salah tetapi saya tidak menemukan apa pun" dan "kesalahan I / O terjadi" adalah bermakna.Banyak implementasi fungsi pustaka C
system
menggunakan kode keluar 127 untuk menunjukkan program tidak ada atau gagal untuk memulai.Pada Windows,
NTSTATUS
kode (yang tersebar secara tidak nyaman di seluruh ruang angka 32-bit) dapat digunakan sebagai kode keluar, terutama kode yang mengindikasikan proses dihentikan karena kelakuan buruk bencana (misSTATUS_STACK_OVERFLOW
.).Anda tidak dapat mengandalkan program apa pun yang mematuhi salah satu dari konvensi ini. Satu-satunya aturan yang dapat diandalkan adalah bahwa kode keluar 0 berhasil dan yang lainnya adalah semacam kegagalan. (Perhatikan bahwa C89 ini
EXIT_SUCCESS
adalah tidak dijamin memiliki nilai nol, namunexit(0)
diperlukan untuk berperilaku identik denganexit(EXIT_SUCCESS)
. Bahkan jika nilai-nilai tidak sama)sumber
Tidak ada kode keluar yang memiliki arti khusus, tetapi nilai dalam
$?
mungkin memiliki arti khusus.Cara Bourne Shell dan ksh93 menangani dan meneruskan kode keluar dan situasi kesalahan ke variabel shell
$?
adalah masalahnya. Bertentangan dengan apa yang Anda daftarkan, hanya nilai-nilai berikut untuk yang$?
memiliki arti khusus:Selain itu, ada shell yang tidak ditentukan dan rentang
$?
kode khusus platform > 128 yang dicadangkan untuk program yang terganggu oleh sinyal:Nilai-nilai lain tidak memberikan masalah karena mereka dapat dibedakan dari nilai-
$?
nilai khusus shell .Secara khusus, nilai 1 dan 2 tidak digunakan untuk kondisi khusus tetapi hanya kode keluar yang digunakan oleh perintah builtin yang dapat bertindak sama ketika mereka tidak ada builtin. Jadi sepertinya penunjuk ke panduan skrip bash yang Anda berikan bukan manual yang baik karena hanya mencantumkan kode yang digunakan oleh bash tanpa berkomentar apakah kode tertentu adalah nilai khusus yang harus dihindari untuk skrip sendiri.
Versi yang lebih baru dari Bourne Shell menggunakan
waitid()
alih-alihwaitpid()
menunggu program untuk keluar danwaitid()
(diperkenalkan 1989 untuk SVr4) menggunakan antarmuka syscall yang lebih baik (mirip dengan apa yang sudah digunakan UNOS pada 1980).Ketika versi Bourne Shell yang lebih baru menyandikan alasan keluar dalam variabel terpisah
${.sh.code}
/${.sh.codename}
daripada kode keluar yang ada di${.sh.status}
/${.sh.termsig}
, lihat http://schillix.sourceforge.net/man/man1/bosh.1.html , kode keluar tidak kelebihan beban dengan status khusus, dan, sebagai akibat dari menggunakan `waitid (), Bourne Shell sekarang mendukung pengembalian semua 32 bit dari kode keluar - bukan hanya bit 8 yang rendah.BTW: berhati-hatilah untuk tidak melakukan
exit(256)
atau mirip dari C-program atau skrip shell, karena ini menghasilkan$?
ditafsirkan sebagai 0 di shell klasik.sumber
waitid()
bug ini sekitar akhir Mei. Orang-orang FreeBSD memperbaiki masalah dalam waktu 20 jam, orang-orang Linux tidak tertarik untuk memperbaiki bug mereka. ... dan orang-orang Cygwin mengatakan bahwa mereka bug oleh bug yang kompatibel dengan Linux ;-)_exit
. Harap tautkan laporan bug FreeBSD yang Anda maksud, mungkin saya salah memahami masalah yang Anda jelaskan.${.sh.}
variabel. Memang benar, bahwa Anda mengatakan "Bourne" dan bukan "Bourne-turunan" (meskipun Anda memasukkan ksh93)./bin/sh
dapat diandalkan untuk berperilaku secara konsisten menggunakan kode keluar lintas-platform khusus ini, yang tidak benar. (Saya tidak peduli apakah sistem tertentu/bin/sh
dapat dikatakan sebagai "shell Bourne nyata". Jauh lebih penting untuk mengetahui bahwa semua ini tidak ada dalam POSIX, dan bahwa sebagian besar hal yang Anda kutip sebagai "sistem Unix nyata" tidak t tetap menyediakan POSIX-compliant/bin/sh
.)Untuk skrip shell, saya kadang-kadang in-source setara
sysexist.h
shell dengan kode keluar shell-dilindungi (diawali denganS_EX_
), yang saya beri namaexit.sh
Itu pada dasarnya:
Dan dapat dihasilkan dengan:
Saya tidak banyak menggunakannya, tetapi yang saya gunakan adalah fungsi shell yang membalikkan kode kesalahan ke format string mereka. Saya sudah menamainya
exit2str
. Dengan asumsi Anda telah menamaiexit.sh
generator di atasexit.sh.sh
, kode untukexit2str
dapat dihasilkan dengan (exit2str.sh.sh
):Saya menggunakan ini di
PS1
shell interaktif saya sehingga setelah setiap perintah saya jalankan, saya bisa melihat status keluar dan bentuk string-nya (jika memang memiliki bentuk string yang dikenal):Untuk mendapatkan ini, Anda memerlukan insourcable untuk fungsi exit2str:
dan kemudian menggunakannya di Anda
~/.bashrc
untuk menyimpan dan menerjemahkan kode keluar pada setiap command prompt dan menampilkannya prompt Anda (PS1
):Sangat mudah untuk mengamati bagaimana beberapa program mengikuti konvensi kode keluar dan beberapa tidak, untuk belajar tentang konvensi kode keluar, atau hanya untuk dapat melihat apa yang terjadi lebih mudah. Setelah menggunakannya selama beberapa waktu, saya dapat mengatakan bahwa banyak skrip shell yang berorientasi sistem mengikuti konvensi.
EX_USAGE
sangat umum, meskipun kode lain, tidak banyak. Saya mencoba mengikuti kebaktian dari waktu ke waktu, meskipun selalu ada$S_EX_ANY
(1) untuk orang malas (saya adalah satu).sumber
Selama Anda mendokumentasikan kode keluar Anda sehingga Anda mengingatnya satu tahun dari sekarang ketika Anda harus kembali dan mengubah skrip Anda akan baik-baik saja. Gagasan "kode keluar yang dicadangkan" tidak benar-benar berlaku lagi selain untuk mengatakan itu adalah kebiasaan untuk digunakan
0
sebagai kode sukses dan apa pun sebagai kode kegagalan.sumber
Referensi terbaik yang bisa saya temukan adalah ini: http://tldp.org/LDP/abs/html/exitcodes.html
Menurut Ini:
1
adalah catchall umum untuk kesalahan, dan saya selalu melihatnya digunakan untuk kesalahan yang ditentukan pengguna.2
adalah untuk penyalahgunaan shell built in, seperti kesalahan sintaksisUntuk menjawab pertanyaan Anda secara langsung skrip Anda akan baik-baik saja menggunakan kode kesalahan yang disediakan, itu akan berfungsi seperti yang diharapkan dengan asumsi Anda menangani kesalahan berdasarkan kode kesalahan = 1/2/3.
Namun, mungkin akan membingungkan jika Anda menemukan orang yang tahu dan menggunakan kode kesalahan yang dipesan, yang tampaknya sangat jarang.
Pilihan lain yang tersedia untuk Anda adalah mengulang kesalahan jika ada satu dan kemudian keluar, dengan asumsi skrip Anda mengikuti konvensi Linux "tidak ada berita adalah kabar baik" dan tidak ada gema tentang kesuksesan.
sumber
Berdasarkan jawaban yang saya terima (sulit untuk memilih salah satu dari yang lain), tidak berbahaya untuk menunjukkan jenis kesalahan tertentu dengan menggunakan kode keluar yang juga digunakan Bash. Bash (atau shell Unix lainnya) tidak akan melakukan sesuatu yang istimewa (seperti menjalankan penangan pengecualian) jika skrip pengguna keluar dengan salah satu kode kesalahan ini.
Tampaknya penulis Advanced Bash-Scripting Guide setuju dengan upaya BSD untuk membakukan kode keluar (
sysexits.h
) dan hanya merekomendasikan bahwa ketika pengguna menulis skrip shell, mereka tidak menentukan kode keluar yang bertentangan dengan kode keluar yang sudah ditentukan sebelumnya. digunakan, yaitu, mereka membatasi kode keluar khusus mereka ke 50 kode status yang tersedia dalam kisaran 64-113.Saya menghargai ide (dan alasannya) tetapi saya lebih suka jika penulis lebih eksplisit bahwa tidak berbahaya untuk mengabaikan saran - selain dari kasus di mana konsumen skrip sedang memeriksa kesalahan seperti contoh yang dikutip dari 127 (
command not found
).Spesifikasi POSIX yang relevan
Saya meneliti apa yang dikatakan POSIX tentang kode keluar dan spesifikasi POSIX tampaknya sesuai dengan penulis Advanced Bash-Scripting Guide. Saya telah mengutip spesifikasi POSIX yang relevan (penekanan saya):
Status Keluar untuk Perintah
The
exit
utilitasInformasi lebih lanjut
Untuk apa nilainya, saya dapat memverifikasi semua kecuali satu dari daftar Kode Keluar Dengan Makna Khusus . Tabel kode keluar ini bermanfaat karena memberikan rincian lebih lanjut - dan contoh cara membuat kode kesalahan yang didokumentasikan dalam referensi Bash .
Mencoba menghasilkan status keluar dari 128
Menggunakan Bash versi 3.2.25 dan 4.2.46, saya mencoba untuk melemparkan
128 Invalid argument to exit
kesalahan tetapi setiap kali saya menerima 255 (Keluar status di luar jangkauan). Misalnya, jikaexit 3.14159
dijalankan sebagai bagian dari skrip shell atau dalam shell anak interaktif, shell keluar dengan kode255
:Untuk lebih menyenangkan, saya juga mencoba menjalankan program C sederhana tetapi dalam kasus ini, tampaknya
exit(3)
fungsinya hanya mengkonversi float ke int (3 dalam hal ini) sebelum keluar:sumber