cmd && echo "$?"
sẽ không hoạt động vì nó chỉ cần in các số 0 ( echo
sẽ 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ư time
lệ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/tty
trong chức năng, chúng tôi vẫn có thể sử dụng tellexit
vớ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 local
này yêu cầu ash
/ pdksh
/ bash
/ zsh
, hoặc bạn có thể thay đổi nó thành typeset
mộ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 ...