cmd && echo "$?"
не будет работать, поскольку по необходимости будет печатать только нули (, а echo
будет выполняться только после успешного завершения предыдущей команды ).
Вот вам короткая оболочка:
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
Перенаправляя printf
на /dev/tty
в функции, мы по-прежнему можем использовать tellexit
с перенаправлениями, не получая мусор в нашем стандартном выводе или потоках ошибок:
$ 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
, что также понимают некоторые другие оболочки.)
sort file | awk '{print > substr($0, 3, 1) ".txt"}'
Выводит каждую строку в файл, имя которого является третьим символом в строке, за которым следует .txt
.
Расширение сообщения @StephaneChazelas
sort -k1.3 | awk '{print > substr($0, 3, 1) ".txt"}'
На самом деле строки будут отсортированы справа от третьего символа. Другими словами, он будет игнорировать первые два символа в каждой строке при выполнении sort
перед их выводом awk
.