Wednesday, 22 March 2017

bash exit status không là -1

Trong một đề tuyển dụng nào đó, có một yêu cầu là: script trả về exit status -1 nếu phát hiện lỗi.

exit status của một câu lệnh / script / chương trình là một giá trị số được trả về khi chương trình kết thúc.
Thông thường, chương trình trả về 0 tức là đã thành công, và khác 0 nghĩa là lỗi.



Dùng bash, đơn giản ta sẽ gõ câu lệnh built-in trong bash: exit -1
$ echo "exit -1" > /tmp/test.sh
$ bash /tmp/test.sh
$ echo $?
255
Exit code ở đây là 255 chứ không phải -1. Thử với một giá trị khác:
$ echo "exit 5" > /tmp/test5.sh
$ bash /tmp/test5.sh
$ echo $?
5
Từ man 1 bash ta có:
The exit status of an executed command is the value returned by the waitpid system call or equivalent function. Exit statuses fall between 0 and 255, though, as explained below, the shell may use values above 125 specially. Exit statuses from shell builtins and compound commands are also limited to this range.
Tức giá trị exit status chỉ nằm trong khoảng 0-255.
Tài liệu về câu lệnh exit:
exit [n]
Cause the shell to exit with a status of n. If n is omitted, the exit status is that of the last command executed. A trap on EXIT is executed before the shell terminates.
Thử exit ngoài đoạn giá trị cho phép xem có gì xảy ra:
$ echo 'exit 259' > test259.sh
$ bash test259.sh
$ echo $?
3

$ echo 'exit 256' > test256.sh
$ bash test256.sh
$ echo $?
0
Vậy theo quan sát, các giá trị ngoài khoảng 0-255 sẽ được tính bằng cách chia cho 256 lấy phần dư.
In [35]: -1 % 256
Out[35]: 255

In [36]: 259 % 256
Out[36]: 3
Yêu cầu exit với status -1 là một yêu cầu không chính xác.

Các exit status của bash:
  • 0: thành công
  • khác 0: thất bại
  • 127: không tìm thấy câu lệnh
  • 126: tìm thấy câu lệnh nhưng không "executable"
  • 2: Tất các các bash built-in command return 2 nếu bị dùng sai
  • N+128: với N là signal mà process nhận được và kết thúc. VD: nhận SIGTERM (15) sẽ exit với status code 15 + 128 = 143.
Chạy 1 script và gửi SIGTERM cho nó:
$ echo 'sleep 1000' > /tmp/sleeplong.sh
$ bash /tmp/sleeplong.sh # chạy lệnh kill -s SIGTERM PID ở một cửa sổ khác
Terminated: 15
$ echo $?
143
Theo code của Bash 4.4:
$ grep status builtins/common.c
/* Get an eight-bit status value from LIST */
  int status;
  status = sval & 255;
  return status;
Giá trị status được return là giá trị sau khi đã thực hiện phép AND bitwise với 255, thử trên Python3:
In [42]: -1 & 255
Out[42]: 255

In [43]: 259 & 255
Out[43]: 3

In [44]: 256 & 255
Out[44]: 0

Vậy bash không bao giờ exit status ngoài khoảng 0-255 cả.
Điều này chưa chắc đúng với các ngôn ngữ khác.

Tham khảo: man 1 bash.
Bài viết sử dụng:
$ python --version
Python 3.5.1
$ bash --version
GNU bash, version 4.3.46
Hết.
HVN at http://www.familug.org/ and http://pymi.vn

Đăng ký học #Python tại #HàNội , lớp khai giảng giữa tháng 4, 2017: https://pymi.vn/

Nhập email vào http://invite.pymi.vn/ để nhận thư mời tham gia forum hỏi đáp Python, Django, Golang ...