cmd && echo "$?"sẽ không hoạt động vì nó chỉ cần in các số 0 ( echosẽ chỉ thực hiện khi hoàn thành thành công lệnh trước).
Đây là một hàm shell ngắn dành cho bạn:
tellexit () {
"$@"
local err="$?"
printf 'exit code\t%d\n' "$err" >/dev/tty
return "$err"
}
Điều này in mã thoát của lệnh đã cho theo cách tương tự như timelệnh.
$ tellexit echo "hello world"
hello world
exit code 0
$ tellexit false
exit code 1
Bằng cách chuyển hướng printfđến /dev/ttytrong chức năng, chúng tôi vẫn có thể sử dụng tellexitvới các chuyển hướng mà không nhận được rác trong luồng đầu ra tiêu chuẩn hoặc lỗi:
$ tellexit bash -c 'echo hello; echo world >&2' >out 2>err
exit code 0
$ cat out
hello
$ cat err
world
Bằng cách lưu mã thoát trong một biến, chúng tôi có thể trả lại mã cho người gọi:
$ tellexit false || echo 'failed'
exit code 1
failed
Một phiên bản fancier của cùng chức năng cũng in tín hiệu đã giết lệnh nếu mã thoát lớn hơn 128 (có nghĩa là nó bị chấm dứt do tín hiệu):
tellexit () {
"$@"
local err="$?"
if [ "$err" -gt 128 ]; then
printf 'exit code\t%d (%s)\n' "$err" "$(kill -l "$err")" >/dev/tty
else
printf 'exit code\t%d\n' "$err" >/dev/tty
fi
return "$err"
}
Kiểm tra:
$ tellexit sh -c 'kill $$'
exit code 143 (TERM)
$ tellexit sh -c 'kill -9 $$'
Killed
exit code 137 (KILL)
(Điều localnày yêu cầu ash/ pdksh/ bash/ zsh, hoặc bạn có thể thay đổi nó thành typesetmột vài shell khác cũng hiểu.)
sleep 1 && echo $?sẽ chỉ in mã của tế bào ngủ khi nó bằng không ...