Exit

記錄命令的退出程式碼,類似於時間命令

  • September 9, 2017

使用

time sleep 1

產量:

$ time sleep 1

real    0m1.005s
user    0m0.001s
sys     0m0.001s

有沒有我可以用來列印退出程式碼sleep或我想執行的任何命令的命令?

喜歡的東西:

$ log-exit-code sleep 1

也許這足夠了?

sleep 1 && echo "$?"

cmd && echo "$?"不起作用,因為它必然只列印零(echo只有在成功完成前面的命令時才會執行)。

這是一個簡短的 shell 函式:

tellexit () {
   "$@"

   local err="$?"
   printf 'exit code\t%d\n' "$err" >/dev/tty
   return "$err"
}

這以與命令類似的方式列印給定命令的退出程式碼time

$ tellexit echo "hello world"
hello world
exit code       0

$ tellexit false
exit code       1

通過在函式中重定向printfto /dev/tty,我們仍然可以使用tellexitwith 重定向,而不會在標準輸出或錯誤流中出現垃圾:

$ tellexit bash -c 'echo hello; echo world >&2' >out 2>err
exit code       0
$ cat out
hello
$ cat err
world

通過將退出程式碼保存在變數中,我們可以將其返回給呼叫者:

$ tellexit false || echo 'failed'
exit code       1
failed

如果退出程式碼大於 128(這意味著它因信號而終止),則相同函式的更高級版本也會列印殺死命令的信號:

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"
}

測試:

$ tellexit sh -c 'kill $$'
exit code       143 (TERM)

$ tellexit sh -c 'kill -9 $$'
Killed
exit code       137 (KILL)

(這個local東西需要ash/ pdksh/ bash/ zsh,或者你可以把它改成typeset其他幾個 shell 也能理解的。)

GNUtime對此有一個選擇:

time -f %x sleep 1
0

通過退出程式碼1,除非被信號2殺死:

$ /usr/bin/time -f %x sleep 1; echo $?
0
0

$ /usr/bin/time -f %x sleep 2x; echo $?
sleep: invalid time interval ‘2x’
Try 'sleep --help' for more information.
1
1

$ /usr/bin/time -f %x sleep 60s; echo $? # Press ^C before a minute elapses
0
2

如果您想了解/處理信號終止情況,請傳遞-v並 grep 字元串的 stderr Command terminated by signal


1感謝 Olivier Dulac 注意到退出程式碼通過。

2另外,感謝 Stéphane Chazelas 指出終止信號退出程式碼未通過。

引用自:https://unix.stackexchange.com/questions/391028