กระบวนการสามารถเรียกการเรียกของ_exit()
ระบบ (บน Linux ดูเพิ่มเติมที่exit_group()
) ด้วยอาร์กิวเมนต์จำนวนเต็มเพื่อรายงานรหัสออกไปยังผู้ปกครอง แม้ว่ามันจะเป็นจำนวนเต็มเพียง 8 บิตที่สำคัญน้อยที่สุดเท่านั้นที่มีให้กับผู้ปกครอง (ยกเว้นว่าเมื่อใช้waitid()
หรือจัดการกับ SIGCHLD ในผู้ปกครองในการดึงรหัสที่แม้ว่าจะไม่ได้อยู่บน Linux)
โดยทั่วไปผู้ปกครองจะทำwait()
หรือwaitpid()
รับสถานะลูกของตนเป็นจำนวนเต็ม (แม้ว่าจะwaitid()
มีความหมายที่แตกต่างกันบ้างก็สามารถใช้ได้เช่นกัน)
บน Linux และ Unices ที่สุดถ้ากระบวนการยกเลิกโดยปกติบิต 8-15 ที่สถานะexit()
จำนวนจะมีรหัสที่ออกเป็นส่งผ่านไปยัง ถ้าไม่เช่นนั้นบิตที่มีนัยสำคัญน้อยที่สุด 7 (0 ถึง 6) จะมีหมายเลขสัญญาณและบิต 7 จะถูกตั้งค่าหากแกนถูกทิ้ง
perl
's $?
เช่นมีตัวเลขที่ที่กำหนดโดยwaitpid()
:
$ perl -e 'system q(kill $$); printf "%04x\n", $?'
000f # killed by signal 15
$ perl -e 'system q(kill -ILL $$); printf "%04x\n", $?'
0084 # killed by signal 4 and core dumped
$ perl -e 'system q(exit $((0xabc))); printf "%04x\n", $?'
bc00 # terminated normally, 0xbc the lowest 8 bits of the status
เชลล์ที่มีลักษณะคล้ายบอร์นยังสร้างสถานะการออกของคำสั่ง run ล่าสุดใน$?
ตัวแปรของตนเอง อย่างไรก็ตามมันไม่ได้มีหมายเลขที่ส่งคืนโดยตรงโดยตรงwaitpid()
แต่เป็นการแปลงที่มันและมันแตกต่างกันระหว่างเปลือกหอย
สิ่งที่พบได้ทั่วไประหว่างเชลล์ทั้งหมดคือที่$?
มีบิต 8 บิตต่ำสุดของรหัสออก (จำนวนที่ส่งให้exit()
) หากกระบวนการยุติลงตามปกติ
ตำแหน่งที่แตกต่างคือเมื่อกระบวนการถูกยกเลิกโดยสัญญาณ ในทุกกรณีและเป็นสิ่งที่ POSIX ต้องการจำนวนจะมากกว่า 128 POSIX ไม่ได้ระบุค่าที่อาจเป็น ในทางปฏิบัติแม้ว่าในทุกเชลล์ที่มี Bourne เหมือนที่ฉันรู้จักบิตต่ำสุด 7 บิต$?
จะมีหมายเลขสัญญาณ แต่n
หมายเลขสัญญาณอยู่ที่ไหน
ในเถ้า zsh, pdksh, ทุบตีบอร์นเปลือกเป็น$?
128 + n
สิ่งที่หมายถึงที่อยู่ในเปลือกหอยเหล่านั้นถ้าคุณได้รับ$?
ของ129
คุณไม่ทราบว่ามันเป็นเพราะกระบวนการออกด้วยexit(129)
หรือไม่ว่าจะถูกฆ่าตายโดยสัญญาณ1
( HUP
ในระบบส่วนใหญ่) แต่เหตุผลคือเชลล์นั้นเมื่อพวกเขาออกจากตัวเองโดยค่าเริ่มต้นกลับสถานะทางออกของคำสั่งที่ออกล่าสุด ด้วยการทำให้แน่ใจว่า$?
จะไม่เกิน 255 ซึ่งจะช่วยให้มีสถานะทางออกที่สอดคล้องกัน:
$ bash -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
bash: line 1: 16720 Terminated sh -c "kill \$\$"
8f # 128 + 15
$ bash -c 'sh -c "kill \$\$"; exit'; printf '%x\n' "$?"
bash: line 1: 16726 Terminated sh -c "kill \$\$"
8f # here that 0x8f is from a exit(143) done by bash. Though it's
# not from a killed process, that does tell us that probably
# something was killed by a SIGTERM
ksh93
, เป็น$?
256 + n
นั่นหมายความว่าจากคุณค่าของ$?
คุณสามารถแยกความแตกต่างระหว่างกระบวนการที่ถูกฆ่าและไม่ถูกฆ่า เวอร์ชันที่ใหม่กว่าของksh
ถ้าออก$?
มากกว่า 255 ฆ่าตัวเองด้วยสัญญาณเดียวกันเพื่อที่จะสามารถรายงานสถานะการออกเดียวกันกับผู้ปกครอง ในขณะที่ฟังดูเป็นความคิดที่ดีหมายความว่าksh
จะสร้างการถ่ายโอนข้อมูลหลักพิเศษ (อาจเขียนทับอีกรายการหนึ่ง) หากกระบวนการถูกฆ่าโดยสัญญาณสร้างแกน:
$ ksh -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
ksh: 16828: Terminated
10f # 256 + 15
$ ksh -c 'sh -c "kill -ILL \$\$"; exit'; printf '%x\n' "$?"
ksh: 16816: Illegal instruction(coredump)
Illegal instruction(coredump)
104 # 256 + 15, ksh did indeed kill itself so as to report the same
# exit status as sh. Older versions of `ksh93` would have returned
# 4 instead.
ที่คุณสามารถพูดได้ว่ามีข้อผิดพลาดคือksh93
ฆ่าตัวเองแม้ว่าจะ$?
มาจากreturn 257
ฟังก์ชั่นที่ทำโดย:
$ ksh -c 'f() { return "$1"; }; f 257; exit'
zsh: hangup ksh -c 'f() { return "$1"; }; f 257; exit'
# ksh kills itself with a SIGHUP so as to report a 257 exit status
# to its parent
yash
. yash
เสนอการประนีประนอม มันกลับ256 + 128 + n
มา นั่นหมายความว่าเราสามารถแยกความแตกต่างระหว่างกระบวนการที่ถูกฆ่าและกระบวนการที่ถูกยกเลิกได้อย่างถูกต้อง และเมื่อออกมามันจะรายงาน128 + n
โดยไม่ต้องฆ่าตัวตายและผลข้างเคียงที่มันสามารถมีได้
$ yash -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
18f # 256 + 128 + 15
$ yash -c 'sh -c "kill \$\$"; exit'; printf '%x\n' "$?"
8f # that's from a exit(143), yash was not killed
เพื่อรับสัญญาณจากค่าของ$?
วิธีการพกพาคือการใช้kill -l
:
$ /bin/kill 0
Terminated
$ kill -l "$?"
TERM
(สำหรับการพกพาคุณไม่ควรใช้หมายเลขสัญญาณเพียงชื่อสัญญาณเท่านั้น)
บนแนวรบที่ไม่ใช่บอร์น:
อาจจะเพื่อความสมบูรณ์เราควรจะพูดถึงzsh
's $pipestatus
และbash
' s $PIPESTATUS
อาร์เรย์ที่มีสถานะออกจากส่วนประกอบของท่อที่ผ่านมา
และเพื่อความสมบูรณ์เมื่อพูดถึงฟังก์ชั่นเชลล์และไฟล์ที่มาโดยฟังก์ชั่นเริ่มต้นกลับมาพร้อมกับสถานะออกจากการทำงานของคำสั่งสุดท้าย แต่ยังสามารถตั้งค่าสถานะการส่งคืนได้อย่างชัดเจนด้วยreturn
builtin และเราเห็นความแตกต่างบางอย่างที่นี่:
bash
และmksh
(ตั้งแต่ R41 การถดถอย ^ Wchange แนะนำโดยเจตนา ) จะตัดทอนหมายเลข (บวกหรือลบ) เป็น 8 บิต ดังนั้นสำหรับตัวอย่างเช่นreturn 1234
จะตั้ง$?
ไป210
, return -- -1
จะตั้ง$?
255
zsh
และpdksh
(และอนุพันธ์อื่นที่ไม่ใช่mksh
) อนุญาตเลขจำนวนเต็มฐานสิบแบบ 32 บิต (-2 31ถึง 2 31 -1) (และตัดจำนวนเป็น32 บิต)
ash
และyash
อนุญาตให้จำนวนเต็มบวกใด ๆ จาก 0 ถึง 2 31 -1 และส่งกลับข้อผิดพลาดสำหรับตัวเลขใด ๆ จากนั้น
ksh93
สำหรับreturn 0
การreturn 320
ตั้งค่า$?
ตามที่เป็น แต่สำหรับสิ่งอื่นให้ตัดเหลือ 8 บิต ระวังดังที่ได้กล่าวไปแล้วว่าการส่งคืนตัวเลขระหว่าง 256 ถึง 320 อาจทำให้เกิดksh
การฆ่าตัวตายเมื่อออกจาก
rc
และes
อนุญาตให้ส่งคืนรายการอะไรก็ได้
นอกจากนี้โปรดทราบว่าบางเชลล์ใช้ค่าพิเศษของ$?
/ $status
เพื่อรายงานเงื่อนไขข้อผิดพลาดบางอย่างที่ไม่ใช่สถานะการออกของกระบวนการเช่น127
หรือ126
สำหรับคำสั่งไม่พบหรือไม่สามารถเรียกใช้งานได้ (หรือข้อผิดพลาดทางไวยากรณ์ในไฟล์ที่มา) ...
killall myScript
ผลงานของคุณดังนั้นการกลับมาของ killall (และไม่ใช่สคริปต์!) คือ 0 คุณสามารถวางkill -x $$
[x เป็นหมายเลขสัญญาณและ $$ มักจะขยายโดยเชลล์ไปยัง PID ของสคริปต์นั้น (ทำงานเป็น sh, bash, ... )] ภายในสคริปต์แล้วทดสอบว่าอะไรคือแก่นทางออกของมัน