Berapakah nilai min dan maks dari kode keluar berikut di Linux:
- Kode keluar kembali dari biner yang dapat dieksekusi (misalnya: program C).
- Kode keluar kembali dari skrip bash (saat memanggil
exit
). - Kode keluar kembali dari fungsi (saat memanggil
return
). Saya pikir ini antara0
dan255
.
linux
executable
function
exit-status
pengguna271801
sumber
sumber
return
, Tentu saja, shell builtin.bash
shell. Beberapa shell lain sepertizsh
dapat mengembalikan nilai 32 bit apa pun yang ditandatangani seperti untukexit
. Beberapa sukarc
ataues
dapat mengembalikan data dari salah satu jenis yang mereka dukung (skalar atau daftar). Lihat tanya jawab terkait untuk perincian.Jawaban:
Nomor yang diteruskan ke sistem
_exit()
/exit_group()
panggilan (kadang-kadang disebut sebagai kode keluar untuk menghindari ambiguitas dengan status keluar yang juga mengacu pada penyandian kode keluar atau nomor sinyal dan info tambahan tergantung pada apakah proses itu dibunuh atau keluar secara normal ) bertipeint
, jadi pada sistem mirip Unix seperti Linux, biasanya integer 32bit dengan nilai dari -2147483648 (-2 31 ) hingga 2147483647 (2 31 -1).Namun, pada semua sistem, ketika proses induk (atau subreaper anak atau
init
jika orang tua meninggal) menggunakanwait()
,waitpid()
,wait3()
,wait4()
panggilan sistem untuk mengambilnya, hanya 8 bit rendah dari itu tersedia (nilai 0 sampai 255 (2 8 - 1)).Saat menggunakan
waitid()
API (atau penangan sinyal di SIGCHLD), pada sebagian besar sistem (dan seperti POSIX sekarang lebih jelas mensyaratkan dalam edisi standar 2016 (lihat_exit()
spesifikasi )), angka lengkap tersedia (disi_status
bidang struktur yang dikembalikan ). Namun itu tidak terjadi di Linux yang juga memotong angka menjadi 8 bit denganwaitid()
API, meskipun itu kemungkinan akan berubah di masa depan.Secara umum, Anda hanya ingin menggunakan nilai 0 (umumnya berarti sukses) menjadi 125 saja, karena banyak shell menggunakan nilai di atas 128 dalam
$?
representasi mereka dari status keluar untuk menyandikan nomor sinyal dari suatu proses yang terbunuh dan 126 dan 127 untuk khusus kondisi.Anda mungkin ingin menggunakan 126 hingga 255
exit()
untuk mengartikan hal yang sama seperti yang mereka lakukan untuk shell$?
(seperti ketika skrip melakukannyaret=$?; ...; exit "$ret"
). Menggunakan nilai di luar 0 -> 255 umumnya tidak berguna. Anda biasanya hanya akan melakukannya jika Anda tahu orang tua akan menggunakanwaitid()
API pada sistem yang tidak terpotong dan Anda memiliki kebutuhan untuk rentang nilai 32-bit. Perhatikan bahwa jika Anda melakukanexit(2048)
misalnya, itu akan dilihat sebagai keberhasilan oleh orang tua menggunakanwait*()
API tradisional .Info lebih lanjut di:
T&J tersebut semoga dapat menjawab sebagian besar pertanyaan Anda yang lain dan mengklarifikasi apa yang dimaksud dengan status keluar . Saya akan menambahkan beberapa hal lagi:
Suatu proses tidak dapat berakhir kecuali itu dimatikan atau memanggil sistem
_exit()
/exit_group()
panggilan. Ketika Anda kembali darimain()
dalamC
, libc memanggil sistem itu memanggil dengan nilai kembali.Sebagian besar bahasa memiliki
exit()
fungsi yang membungkus panggilan sistem itu, dan nilai yang diambilnya, jika ada yang umumnya dilewatkan seperti halnya panggilan sistem. (perhatikan bahwa mereka umumnya melakukan lebih banyak hal seperti pembersihan yang dilakukan olehexit()
fungsi C yang membersihkan buffer stdio, menjalankanatexit()
kait ...)Setidaknya itulah yang terjadi:
Anda sesekali melihat beberapa yang mengeluh ketika Anda menggunakan nilai di luar 0-255:
Beberapa shell mengeluh ketika Anda menggunakan nilai negatif:
POSIX membiarkan perilaku tidak terdefinisi jika nilai yang diteruskan ke
exit
builtin khusus berada di luar 0-> 255.Beberapa kerang menunjukkan beberapa perilaku tak terduga jika Anda melakukannya:
bash
(danmksh
tetapi tidakpdksh
berdasarkan yang mana) mengambil sendiri untuk memotong nilai menjadi 8 bit:Jadi di shell itu, jika Anda ingin keluar dengan nilai di luar 0-255, Anda harus melakukan sesuatu seperti:
Yaitu menjalankan perintah lain dalam proses yang sama yang dapat memanggil system call dengan nilai yang Anda inginkan.
seperti yang disebutkan pada T&J lainnya,
ksh93
memiliki perilaku paling aneh untuk nilai keluar dari 257 hingga 256 + max_signal_number di mana alih-alih memanggilexit_group()
, ia membunuh dirinya sendiri dengan sinyal yang sesuai¹.dan sebaliknya memotong angka seperti
bash
/mksh
.¹ Namun itu kemungkinan akan berubah di versi berikutnya. Sekarang pengembangan
ksh93
telah diambil alih sebagai upaya komunitas di luar AT&T, perilaku itu, meskipun didorong oleh POSIX, sedang dipulihkansumber
si_status
untuk Linux?int
setidaknya 16 bit, POSIX lebih atau kurang mengharuskannya menjadi setidaknya 32 bit dan lingkungan pemrograman untuk memiliki uint32_t . Saya tidak tahu apakah Linux mendukung lingkungan pemrograman mana pun kecuali intinya, tetapi saya tidak pernah menemukan itu.Minimal
0
, dan itu dianggap sebagai nilai keberhasilan. Semua yang lain adalah kegagalan. Maksimum255
juga dikenal sebagai-1
.Aturan ini berlaku untuk skrip dan file executable lainnya, serta fungsi shell.
Nilai yang lebih besar menghasilkan modulo 256.
sumber
bash
atau yang paling umum digunakan) kode keluar yang diteruskan keexit
builtin tidak diperlakukan sebagai modulo-256, dan malah menyebabkan kesalahan. (Misalnya, commonexit -1
sebenarnya tidak setara dengan portableexit 255
di kebanyakan shell). Dan apakahexit(-1)
pada level C setara denganexit(255)
detail yang pasti bekerja, tetapi bergantung pada implementasi perilaku yang ditentukan (meskipun ini bukan masalah pada sistem modern yang mungkin Anda gunakan dalam praktiknya).exit(1)
parameter hingga 8 bit.Ini terlihat sangat sederhana, tetapi oh kesengsaraan.
Bahasa C (dan mengikuti sebagian besar bahasa lain secara langsung atau tidak langsung) mensyaratkan bahwa pengembalian dari
main
setara dengan panggilanexit
dengan argumen yang sama dengan nilai pengembalian. Ini adalah bilangan bulat (jenis kembali sangat jelasint
), sehingga pada prinsipnya kisaran akanINT_MIN
untukINT_MAX
.Namun, POSIX menyatakan bahwa hanya 8 bit paling rendah yang dilewatkan
exit
harus disediakan untuk proses induk menunggu, secara harfiah seolah-olah itu "status & 0xFF" .Jadi, dalam praktiknya, kode keluar adalah integer (masih ditandatangani) yang hanya menetapkan 8 bit terendah.
Minimum akan menjadi -128, dan maksimum 127. Tunggu dulu, itu tidak benar. Itu akan menjadi 0 hingga 255.Namun sayang, tentu saja tidak sesederhana itu . Dalam praktiknya, Linux (atau lebih tepatnya bash) melakukannya secara berbeda . Rentang kode pengembalian yang valid adalah 0 hingga 255 (yaitu tidak ditandatangani).
Untuk berada di sisi yang aman dalam hal menghindari kebingungan, mungkin ide yang baik untuk mengasumsikan bahwa kode pengembalian tidak ditandatangani, dan membuang apa pun yang Anda dapatkan dari
wait
menjadi tidak ditandatangani. Dengan cara itu konsisten dengan apa yang Anda lihat di shell. Karena bit paling atas (termasuk yang paling signifikan) dihapus, itu bahkan tidak "salah" karena meskipun secara teknis ditandatangani, nilai aktual selalu tidak ditandatangani (karena bit tanda tidak pernah disetel).Ini juga membantu menghindari kesalahan umum membandingkan kode keluar
-1
, yang untuk beberapa alasan aneh sepertinya tidak pernah muncul bahkan ketika sebuah program keluar dengan-1
(yah, tebak kenapa!).Tentang poin terakhir Anda, kembali dari suatu fungsi, jika fungsi ini kebetulan
main
, maka lihat di atas. Kalau tidak, itu tergantung pada apa jenis kembali fungsi itu, pada prinsipnya bisa apa saja (termasukvoid
)sumber
waitid()
diperkenalkan.waitid()
melakukan hal yang sama, sedikit berbeda. Ini menunggu untuk id tertentu atau benang pun, dan menulis hasil ke menunjuk kesiginfo_t
struktur di manasi_status
adalahint
(jadi ... ditandatangani , sama saja). Namun,exit()
hanya melewati 8 bit paling bawah, jadi ... benar-benar hal yang sama di bawah tenda.exit()
meneruskan semua 32 bit parameter ke kernel danwaitid()
mengembalikan semua 32 bit dari kode keluar. Mungkin Anda memeriksa di Linux di mana tidak ada yang peduli untuk memperbaiki bug. Jika Anda tidak mempercayai saya, periksa pada OS yang sesuai dengan POSIX ...exit
, khususnya baris kedua di bawah "Deskripsi" yang menyatakan: "meskipun hanya 8 bit yang paling tidak signifikan (yaitu, status & 0377) harus tersedia untuk proses induk menunggu " . Begitulah implementasi implementasi yang sesuai - 8 bit paling bawah, bukan 32. Apakah Anda memiliki referensi untuk 32 bit yang diteruskan?waitid()
dansiginfo_t
struktur yang diteruskan ke pengembalianSIGCHLD
handler. semua 32 bit dariexit()
parameter.Keluar dari proses apa pun - apakah itu biner yang dapat dieksekusi, skrip shell, atau apa pun - berkisar dari 0 hingga 255. Mungkin saja untuk memberikan nilai yang lebih besar
exit()
, tetapi hanya 8 bit yang lebih rendah dari status yang tersedia untuk proses lain melaluiwait()
.Fungsi AC dapat dinyatakan sebagai mengembalikan hampir semua jenis. Batas nilai kembaliannya ditentukan sepenuhnya oleh tipe itu: misalnya, -128 hingga 127 untuk fungsi yang kembali
signed char
, atau 0 hingga 4,2 miliar untuk fungsi yang kembaliunsigned int
, atau angka floating-point hingga dan termasukinf
untuk fungsi yang kembalidouble
. Dan itu tidak termasuk tipe non-numerik, sepertivoid *
ataustruct
...sumber