Для сценариев оболочки я иногда вставляю в исходный код эквивалент оболочки sysexist.h
с зарезервированные оболочкой коды выхода (с префиксом S_EX_
), которые я назвал 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; }'
Я не Хотя я использую его много, но я использую функцию оболочки, которая инвертирует коды ошибок в их строковые форматы. Я назвал его 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)$
Чтобы получить их, вам понадобится insourcable для функции 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)\$'
# ...
Это очень удобно для наблюдения за тем, как некоторые программы следуют соглашениям о коде выхода, а некоторые нет, для изучения соглашений о коде выхода или просто для того, чтобы иметь возможность легче увидеть, что происходит.
Пользуясь этим в течение некоторого времени, я могу сказать, что многие сценарии оболочки, ориентированные на систему, действительно следуют соглашениям. EX_USAGE
особенно часто встречается, хотя других кодов не так много. Время от времени я стараюсь следовать правилам, хотя всегда есть $ S_EX_ANY
(1) для ленивых (я один из них).
Я смог решить эту проблему, снова удалив псевдоним с помощьюunalias cd
Это произошло потому, что:
$ type cd
cd is a shell builtin
Ваша система (, как и многие системы Unix ), не имеет внешней cd
команды (, по крайней мере, не по этому пути ). Даже если бы он был, ls
дал бы вам список исходного каталога. Внешняя команда никогда не может изменить каталог вызывающего процесса (вашей оболочки)1 .
Удалите псевдоним из среды с помощью unalias cd
(, а также удалите его определение из всех файлов инициализации оболочки, в которые вы, возможно, добавили его ).
С помощью функции оболочки вы можете заставить ее работать, как обычно cd
, с дополнительным вызовом ls
в конце, если cd
удалось:
cd () {
command cd "$@" && ls -lah
}
или,
cd () { command cd "$@" && ls -lah; }
Это приведет к вызову команды cd
, встроенной в вашу оболочку, с теми же аргументами командной строки, которые вы дали функции. Если изменение каталога прошло успешно, запустится ls
.
Команда command
останавливает рекурсивное выполнение функции оболочкой.
Определение функции (, как написано выше ), будет помещено в файл запуска вашей оболочки. С bash
это может быть ~/.bashrc
. Затем определение функции будет активным в следующем новом сеансе интерактивной оболочки . Если вы хотите, чтобы она была активной сейчас , выполните определение функции, поскольку -находится в приглашении интерактивной оболочки, которое определит ее в рамках вашего текущего интерактивного сеанса.
1 В системах, где cd
доступна как внешняя команда, эта команда также не изменяет каталог для вызывающего процесса. Единственное реальное применение такой команды — обеспечение соответствия POSIX и проверка того, возможно ли изменение каталога на конкретный .