对于shell脚本编写,我有时会将sysexist.h
与shell保留的退出代码(以前缀S_EX_
)一起等价于shell 的源代码,我将其命名为exit.sh
基本上是:
EX_OK=0 # successful termination
EX__BASE=64 # base value for error messages
EX_USAGE=64 # command line usage error
EX_DATAERR=65 # data format error
EX_NOINPUT=66 # cannot open input
EX_NOUSER=67 # addressee unknown
EX_NOHOST=68 # host name unknown
EX_UNAVAILABLE=69 # service unavailable
EX_SOFTWARE=70 # internal software error
EX_OSERR=71 # system error (e.g., can't fork)
EX_OSFILE=72 # critical OS file missing
EX_CANTCREAT=73 # can't create (user) output file
EX_IOERR=74 # input/output error
EX_TEMPFAIL=75 # temp failure; user is invited to retry
EX_PROTOCOL=76 # remote error in protocol
EX_NOPERM=77 # permission denied
EX_CONFIG=78 # configuration error
EX__MAX=78 # maximum listed value
#System errors
S_EX_ANY=1 #Catchall for general errors
S_EX_SH=2 #Misuse of shell builtins (according to Bash documentation); seldom seen
S_EX_EXEC=126 #Command invoked cannot execute Permission problem or command is not an executable
S_EX_NOENT=127 #"command not found" illegal_command Possible problem with $PATH or a typo
S_EX_INVAL=128 #Invalid argument to exit exit 3.14159 exit takes only integer args in the range 0 - 255 (see first footnote)
#128+n Fatal error signal "n" kill -9 $PPID of script $? returns 137 (128 + 9)
#255* Exit status out of range exit -1 exit takes only integer args in the range 0 - 255
S_EX_HUP=129
S_EX_INT=130
#...
可以通过以下方式生成:
#!/bin/sh
src=/usr/include/sysexits.h
echo "# Generated from \"$src\""
echo "# Please inspect the source file for more detailed descriptions"
echo
< "$src" sed -rn 's/^#define *(\w+)\s*(\d*)/\1=\2/p'| sed 's:/\*:#:; s:\*/::'
cat<<'EOF'
#System errors
S_EX_ANY=1 #Catchall for general errors
S_EX_SH=2 #Misuse of shell builtins (according to Bash documentation); seldom seen
S_EX_EXEC=126 #Command invoked cannot execute Permission problem or command is not an executable
S_EX_NOENT=127 #"command not found" illegal_command Possible problem with $PATH or a typo
S_EX_INVAL=128 #Invalid argument to exit exit 3.14159 exit takes only integer args in the range 0 - 255 (see first footnote)
#128+n Fatal error signal "n" kill -9 $PPID of script $? returns 137 (128 + 9)
#255* Exit status out of range exit -1 exit takes only integer args in the range 0 - 255
EOF
$(which kill) -l |tr ' ' '\n'| awk '{ printf "S_EX_%s=%s\n", $0, 128+NR; }'
不过,我使用的不是很多,但是我使用的是一个将错误代码转换为字符串格式的shell函数。我已经命名了exit2str
。假设您已命名上述exit.sh
生成器exit.sh.sh
,则exit2str
可以使用(exit2str.sh.sh
)生成用于的代码:
#!/bin/sh
echo '
exit2str(){
case "$1" in'
./exit.sh.sh | sed -nEe's|^(S_)?EX_(([^_=]+_?)+)=([0-9]+).*|\4) echo "\1\2";;|p'
echo "
esac
}"
我在PS1
交互式外壳程序的中使用此命令,以便在我运行每个命令后,可以看到其退出状态和字符串形式(如果它确实具有已知的字符串形式):
[15:58] pjump@laptop:~
(0=OK)$
[15:59] pjump@laptop:~
(0=OK)$ fdsaf
fdsaf: command not found
[15:59] pjump@laptop:~
(127=S_NOENT)$ sleep
sleep: missing operand
Try 'sleep --help' for more information.
[15:59] pjump@laptop:~
(1=S_ANY)$ sleep 100
^C
[15:59] pjump@laptop:~
(130=S_INT)$ sleep 100
^Z
[1]+ Stopped sleep 100
[15:59] pjump@laptop:~
(148=S_TSTP)$
为了获得这些,您需要为exit2str函数添加一个不可购买的东西:
$ ./exit2str.sh.sh > exit2str.sh #Place this somewhere in your PATH
然后在您~/.bashrc
的代码中使用它保存并翻译每个命令提示符下的退出代码,并在您的提示符(PS1
)中显示该代码:
# ...
. exit2str.sh
PROMPT_COMMAND='lastStatus=$(st="$?"; echo -n "$st"; str=$(exit2str "$st") && echo "=$str"); # ...'
PS1="$PS1"'\n($lastStatus)\$'
# ...
观察某些程序如何遵循退出代码约定,有些不遵循退出代码约定,对于了解退出代码约定,或者只是为了能够更轻松地了解正在发生的事情,这非常方便。使用一段时间以来,我可以说许多面向系统的Shell脚本确实遵循约定。EX_USAGE
尽管其他代码并不多,但是它非常普遍。尽管总是有$S_EX_ANY
(1)懒惰的人(我是其中一员),但我还是会时不时地遵循惯例。