Số truyền cho _exit()
/ exit_group()
cuộc gọi hệ thống (đôi khi được gọi là mã thoát để tránh sự nhập nhằng với trạng thái thoát mà cũng là đề cập đến một mã hóa của một trong hai mã thoát hoặc số tín hiệu và thông tin bổ sung tùy thuộc vào việc quá trình này đã bị giết chết hoặc thoát bình thường ) thuộc loại int
, vì vậy trên các hệ thống giống Unix như Linux, thường là số nguyên 32 bit với các giá trị từ -2147483648 (-2 31 ) đến 2147483647 (2 31 -1).
Tuy nhiên, trên tất cả các hệ thống, khi quá trình cha mẹ (hoặc subreaper trẻ em hoặc init
nếu cha mẹ chết) sử dụng wait()
, waitpid()
, wait3()
, wait4()
cuộc gọi hệ thống để lấy nó, chỉ có 8 bit thấp của nó có sẵn (giá trị 0 đến 255 (2 8 - 1)).
Khi sử dụng waitid()
API (hoặc trình xử lý tín hiệu trên SIGCHLD), trên hầu hết các hệ thống (và như POSIX hiện yêu cầu rõ ràng hơn trong phiên bản 2016 của tiêu chuẩn (xem _exit()
thông số kỹ thuật )), số đầy đủ có sẵn (trong si_status
trường của cấu trúc được trả về ). Tuy nhiên, đó không phải là trường hợp trên Linux, mặc dù cũng cắt ngắn số lượng thành 8 bit với waitid()
API, mặc dù điều đó có thể sẽ thay đổi trong tương lai.
Nói chung, bạn chỉ muốn sử dụng các giá trị 0 (thường có nghĩa là thành công) đến 125, vì nhiều shell sử dụng các giá trị trên 128 để $?
thể hiện trạng thái thoát để mã hóa số tín hiệu của một quá trình bị giết và đặc biệt là 126 và 127 điều kiện.
Bạn có thể muốn sử dụng 126 đến 255 exit()
để có nghĩa tương tự như đối với shell $?
(như khi tập lệnh thực hiện ret=$?; ...; exit "$ret"
). Sử dụng các giá trị ngoài 0 -> 255 thường không hữu ích. Nói chung, bạn chỉ làm điều đó nếu bạn biết cha mẹ sẽ sử dụng waitid()
API trên các hệ thống không cắt bớt và bạn có nhu cầu về phạm vi giá trị 32 bit. Lưu ý rằng nếu bạn làm một exit(2048)
ví dụ, đó sẽ được coi là thành công của cha mẹ bằng cách sử dụng các wait*()
API truyền thống .
Thêm thông tin tại:
Câu hỏi và trả lời đó hy vọng sẽ trả lời hầu hết các câu hỏi khác của bạn và làm rõ ý nghĩa của trạng thái thoát . Tôi sẽ thêm một vài điều nữa:
Một quá trình không thể chấm dứt trừ khi nó bị giết hoặc gọi các cuộc gọi _exit()
/ exit_group()
hệ thống. Khi bạn trở về từ main()
trong C
, libc gọi hệ thống đó gọi với giá trị trả về.
Hầu hết các ngôn ngữ đều có exit()
chức năng bao bọc cuộc gọi hệ thống đó và giá trị mà chúng nhận được, nếu bất kỳ ngôn ngữ nào thường được chuyển như đối với cuộc gọi hệ thống. (lưu ý rằng những người đó thường làm nhiều việc hơn như dọn dẹp được thực hiện bởi exit()
chức năng của C để xóa bộ đệm stdio, chạy atexit()
hook ...)
Đó là trường hợp của ít nhất:
$ strace -e exit_group awk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ strace -e exit_group mawk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ strace -e exit_group busybox awk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ echo | strace -e exit_group sed 'Q1234'
exit_group(1234) = ?
$ strace -e exit_group perl -e 'exit(1234)'
exit_group(1234) = ?
$ strace -e exit_group python -c 'exit(1234)'
exit_group(1234) = ?
$ strace -e exit_group expect -c 'exit 1234'
exit_group(1234) = ?
$ strace -e exit_group php -r 'exit(1234);'
exit_group(1234) = ?
$ strace -e exit_group zsh -c 'exit 1234'
exit_group(1234)
Bạn có thể thấy một số người phàn nàn khi bạn sử dụng một giá trị ngoài 0-255:
$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1) = ?
Một số shell phàn nàn khi bạn sử dụng giá trị âm:
$ strace -e exit_group dash -c 'exit -1234'
dash: 1: exit: Illegal number: -1234
exit_group(2) = ?
$ strace -e exit_group yash -c 'exit -- -1234'
exit: `-1234' is not a valid integer
exit_group(2) = ?
POSIX để lại hành vi không xác định nếu giá trị được chuyển đến exit
nội dung đặc biệt nằm ngoài 0-> 255.
Một số vỏ cho thấy một số hành vi bất ngờ nếu bạn làm:
bash
(và mksh
không pdksh
dựa vào đó) dựa vào chính nó để cắt giá trị thành 8 bit:
$ strace -e exit_group bash -c 'exit 1234'
exit_group(210) = ?
Vì vậy, trong các shell đó, nếu bạn muốn thoát với giá trị ngoài 0-255, bạn phải làm một cái gì đó như:
exec zsh -c 'exit -- -12345'
exec perl -e 'exit(-12345)'
Đó là thực thi một lệnh khác trong cùng một quy trình có thể gọi cuộc gọi hệ thống với giá trị bạn muốn.
như đã đề cập ở câu hỏi và trả lời khác đó, ksh93
có hành vi kỳ lạ nhất đối với các giá trị thoát từ 257 đến 256 + max_signal_number trong đó thay vì gọi exit_group()
, nó sẽ tự giết mình với tín hiệu tương ứng¹.
$ ksh -c 'exit "$((256 + $(kill -l STOP)))"'
zsh: suspended (signal) ksh -c 'exit "$((256 + $(kill -l STOP)))"'
và nếu không thì cắt bớt số như bash
/ mksh
.
Though Điều đó có khả năng thay đổi trong phiên bản tiếp theo. Giờ đây, sự phát triển ksh93
đã được thực hiện như một nỗ lực của cộng đồng bên ngoài AT & T, hành vi đó, mặc dù được khuyến khích bằng cách nào đó bởi POSIX, đang được hoàn nguyên
return
, Tất nhiên, một dựng sẵn vỏ.