Suatu proses dianggap telah selesai dengan benar di Linux jika status keluarnya adalah 0.
Saya telah melihat bahwa kesalahan segmentasi sering mengakibatkan status keluar dari 11, meskipun saya tidak tahu apakah ini hanya konvensi tempat saya bekerja (aplikasi yang gagal seperti itu semuanya internal) atau standar.
Apakah ada kode keluar standar untuk proses di Linux?
linux
error-handling
exit-code
Nathan Fellman
sumber
sumber
Jawaban:
8 bit dari kode kembali dan 8 bit dari jumlah sinyal pembunuhan dicampur menjadi satu nilai pada pengembalian dari
wait(2)
& co. .Bagaimana Anda menentukan status keluar? Secara tradisional, shell hanya menyimpan kode pengembalian 8-bit, tetapi menetapkan bit tinggi jika proses dihentikan secara tidak normal.
Jika Anda melihat hal lain selain ini, maka program tersebut mungkin memiliki
SIGSEGV
pengendali sinyal yang kemudian memanggil denganexit
normal, sehingga sebenarnya tidak terbunuh oleh sinyal. (Program dapat memilih untuk menangani sinyal selainSIGKILL
danSIGSTOP
.)sumber
Bagian 1: Panduan Script Bash Lanjutan
Seperti biasa, Panduan Skrip Bash Lanjutan memiliki informasi hebat : (Ini ditautkan dalam jawaban lain, tetapi ke URL non-kanonik.)
Bagian 2: sysexits.h
Referensi ABSG
sysexits.h
.Di Linux:
sumber
man sysexits
sysexits.h
? The halaman manual semua orang terus referensi hanya prosa. Sebagai contoh referensiEX_OK
tetapi tidak benar-benar mendefinisikannya dengan cara normatif seperti kode lainnya. Apakah ada lagi yang hilang?'1' >>> Catchall untuk kesalahan umum
'2' >>> Penyalahgunaan bawaan shell (menurut dokumentasi Bash)
'126' >>> Perintah yang dipanggil tidak bisa dijalankan
'127' >>> "perintah tidak ditemukan"
'128' >>> Argumen tidak valid untuk keluar
'128 + n' >>> Sinyal kesalahan fatal "n"
'130' >>> Script diakhiri oleh Control-C
'255' >>> Keluar status di luar jangkauan
Ini untuk bash. Namun, untuk aplikasi lain, ada berbagai kode keluar.
sumber
Tidak ada jawaban yang lebih lama yang menggambarkan status keluar 2 dengan benar. Bertentangan dengan apa yang mereka klaim, status 2 adalah apa yang sebenarnya dikembalikan utilitas baris perintah Anda ketika dipanggil dengan tidak benar. (Ya, jawabannya bisa berusia sembilan tahun, memiliki ratusan upvotes, dan masih salah.)
Berikut adalah konvensi status keluar lama yang nyata untuk pemutusan normal, yaitu bukan dengan sinyal:
Misalnya,
diff
mengembalikan 0 jika file yang diperbandingkannya identik, dan 1 jika berbeda. Dengan konvensi lama, program unix kembali keluar Status 2 saat dipanggil tidak benar (pilihan tidak diketahui, nomor yang salah dari argumen, dll) Sebagai contoh,diff -N
,grep -Y
ataudiff a b c
akan semua hasil di$?
menjadi set ke 2. Ini adalah dan telah menjadi praktek sejak hari-hari awal Unix di tahun 1970-an.The jawaban yang diterima menjelaskan apa yang terjadi ketika sebuah perintah diakhiri oleh sinyal. Singkatnya, pengakhiran karena sinyal yang tidak tertangkap menghasilkan status keluar
128+[<signal number>
. Misalnya, terminasi olehSIGINT
( sinyal 2 ) menghasilkan status keluar 130.Catatan
Beberapa jawaban mendefinisikan status keluar 2 sebagai "Penyalahgunaan bash builtins". Ini hanya berlaku ketika bash (atau skrip bash) keluar dengan status 2. Anggap saja ini kasus khusus kesalahan penggunaan yang salah.
Dalam
sysexits.h
, yang disebutkan dalam jawaban paling populer , status keluarEX_USAGE
("kesalahan penggunaan baris perintah") didefinisikan sebagai 64. Tetapi ini tidak mencerminkan kenyataan: Saya tidak mengetahui adanya utilitas Unix umum yang mengembalikan 64 pada permintaan yang salah (contoh selamat datang ). Pembacaan yang hati-hati terhadap kode sumber mengungkapkan bahwasysexits.h
itu aspirasional, dan bukan cerminan dari penggunaan yang sebenarnya:Dengan kata lain, definisi-definisi ini tidak mencerminkan praktik umum pada waktu itu (1993) tetapi sengaja tidak sesuai dengan itu. Sayang sekali.
sumber
more
akan mengatur ulang mode terminal dan keluar dengan status 0 (Anda dapat mencobanya).Tidak ada kode keluar standar, selain 0 artinya berhasil. Non-nol tidak berarti kegagalan juga.
stdlib.h mendefinisikan
EXIT_FAILURE
sebagai 1 danEXIT_SUCCESS
0, tapi hanya itu saja.11 pada segfault menarik, karena 11 adalah nomor sinyal yang digunakan kernel untuk mematikan proses jika terjadi segfault. Kemungkinan ada beberapa mekanisme, baik di kernel atau di shell, yang menerjemahkannya ke dalam kode keluar.
sumber
sysexits.h memiliki daftar kode keluar standar. Sepertinya tanggal kembali ke setidaknya tahun 1993 dan beberapa proyek besar seperti Postfix menggunakannya, jadi saya membayangkan itu cara untuk pergi.
Dari halaman manual OpenBSD:
sumber
Untuk perkiraan pertama, 0 adalah sukses, bukan nol adalah kegagalan, dengan 1 adalah kegagalan umum, dan apa pun yang lebih besar dari satu adalah kegagalan spesifik. Selain pengecualian sepele dari pengujian salah, yang keduanya dirancang untuk memberikan 1 untuk keberhasilan, ada beberapa pengecualian lain yang saya temukan.
Lebih realistis, 0 berarti berhasil atau mungkin gagal, 1 berarti kegagalan umum atau mungkin berhasil, 2 berarti kegagalan umum jika 1 dan 0 keduanya digunakan untuk sukses, tetapi mungkin berhasil juga.
Perintah diff memberikan 0 jika file yang dibandingkan adalah identik, 1 jika mereka berbeda, dan 2 jika biner berbeda. 2 juga berarti kegagalan. Perintah less memberi 1 untuk kegagalan kecuali jika Anda gagal memberikan argumen, dalam hal ini, ia keluar 0 meskipun gagal.
Perintah lebih banyak dan perintah ejaan memberikan 1 untuk kegagalan, kecuali kegagalan itu adalah hasil dari izin yang ditolak, file tidak ada, atau upaya untuk membaca direktori. Dalam semua kasus ini, mereka keluar 0 meskipun gagal.
Kemudian perintah expr memberikan 1 untuk sucess kecuali outputnya adalah string kosong atau nol, dalam hal ini, 0 adalah sucess. 2 dan 3 adalah kegagalan.
Lalu ada kasus di mana keberhasilan atau kegagalan bersifat ambigu. Ketika grep gagal menemukan pola, ia keluar 1, tetapi keluar 2 untuk kegagalan asli (seperti izin ditolak). Klist juga keluar 1 ketika gagal menemukan tiket, meskipun ini sebenarnya bukan kegagalan daripada ketika grep tidak menemukan pola, atau ketika Anda ls direktori kosong.
Jadi, sayangnya, kekuatan unix yang tampaknya tidak memberlakukan seperangkat aturan logis, bahkan pada executable yang sangat umum digunakan.
sumber
Program mengembalikan kode keluar 16 bit. Jika program dimatikan dengan sinyal maka byte orde tinggi berisi sinyal yang digunakan, sebaliknya byte orde rendah adalah status keluar yang dikembalikan oleh programmer.
Bagaimana kode keluar itu ditetapkan ke variabel status $? kemudian terserah shell. Bash menyimpan 7 bit status yang lebih rendah dan kemudian menggunakan 128 + (sinyal nr) untuk menunjukkan sinyal.
Satu-satunya konvensi "standar" untuk program adalah 0 untuk kesuksesan, bukan nol untuk kesalahan. Konvensi lain yang digunakan adalah untuk mengembalikan errno pada kesalahan.
sumber
Kode keluar Unix standar didefinisikan oleh sysexits.h, seperti poster lain yang disebutkan. Kode keluar yang sama digunakan oleh perpustakaan portabel seperti Poco - berikut adalah daftarnya:
http://pocoproject.org/docs/Poco.Util.Application.html#16218
Sinyal 11 adalah sinyal SIGSEGV (pelanggaran segmen), yang berbeda dari kode pengembalian. Sinyal ini dihasilkan oleh kernel sebagai tanggapan terhadap akses halaman yang buruk, yang menyebabkan program berhenti. Daftar sinyal dapat ditemukan di halaman manual sinyal (jalankan "sinyal manusia").
sumber
Ketika Linux mengembalikan 0, itu berarti sukses. Apa pun artinya kegagalan, setiap program memiliki kode keluar sendiri, jadi cukup lama untuk mendaftar semuanya ...!
Tentang kode kesalahan 11, itu memang nomor kesalahan segmentasi, sebagian besar berarti bahwa program mengakses lokasi memori yang tidak ditetapkan.
sumber