Đối với kịch bản lệnh shell, đôi khi tôi nhập nguồn shell tương đương sysexist.h
với mã thoát dành riêng cho shell (có tiền tố S_EX_
), mà tôi đã đặt tênexit.sh
Về cơ bản là:
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
#...
Và có thể được tạo bằng:
#!/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; }'
Mặc dù vậy, tôi không sử dụng nó nhiều, nhưng những gì tôi sử dụng là hàm shell đảo ngược mã lỗi thành các định dạng chuỗi của chúng. Tôi đã đặt tên cho nó exit2str
. Giả sử bạn đã đặt tên cho trình exit.sh
tạo ở trên exit.sh.sh
, mã cho exit2str
có thể được tạo bằng ( 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
}"
Tôi sử dụng cái này trong PS1
shell tương tác của mình để sau mỗi lệnh tôi chạy, tôi có thể thấy trạng thái thoát của nó và dạng chuỗi của nó (nếu nó có dạng chuỗi đã biết):
[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)$
Để có được những thứ này, bạn cần một hàm không thể chấp nhận được cho hàm exit2str:
$ ./exit2str.sh.sh > exit2str.sh #Place this somewhere in your PATH
và sau đó sử dụng nó trong của bạn ~/.bashrc
để lưu và dịch mã thoát trên mỗi dấu nhắc lệnh và hiển thị dấu nhắc của bạn ( PS1
):
# ...
. exit2str.sh
PROMPT_COMMAND='lastStatus=$(st="$?"; echo -n "$st"; str=$(exit2str "$st") && echo "=$str"); # ...'
PS1="$PS1"'\n($lastStatus)\$'
# ...
Nó khá thuận tiện để quan sát cách một số chương trình tuân theo các quy ước mã thoát và một số không, để tìm hiểu về các quy ước mã thoát hoặc chỉ để có thể thấy những gì đang diễn ra dễ dàng hơn. Đã sử dụng nó một thời gian, tôi có thể nói rằng nhiều tập lệnh shell định hướng hệ thống thực hiện theo các quy ước. EX_USAGE
là đặc biệt khá phổ biến, mặc dù các mã khác, không nhiều. Thỉnh thoảng tôi cố gắng tuân theo các quy ước, mặc dù luôn có $S_EX_ANY
(1) cho những người lười biếng (tôi là một).