Ответы:
Используйте fc
для получения предыдущей командной строки. Обычно он используется для редактирования предыдущей командной строки в вашем любимом редакторе, но также имеет режим «списка»:
last_command="$(fc -nl -1)"
caller
и Баш массивы BASH_LINENO
, BASH_SOURCE
и FUNCNAME
делать вид трассировки стека.
Если последняя команда была выполнена без аргументов, она будет сохранена в $_
переменной. Обычно он содержит последний аргумент предыдущей команды - поэтому, если аргументов не было, значением $_
является сама последняя команда.
Другой вариант - узнать подробности последней фоновой команды. Как писал l0b0, $!
содержит его PID - так что вы можете анализировать вывод ps $!
(возможно, с дополнительными опциями форматирования ps
).
Нет, но вы можете получить его во время выполнения, чтобы сохранить для других команд:
$0
Путь текущего сценария оболочки.$FUNCNAME
: "Имя текущей функции.""$@"
: Все параметры текущей команды, указаны отдельно.$!
: "PID (идентификатор процесса) последнего запуска задания в фоновом режиме."$$
: "Идентификатор процесса (PID) самого скрипта."Поэтому полная команда текущего скрипта должна быть "$0" "$@"
. Если это функция, то так и должно быть "$FUNCNAME" "$@"
. Возможно, вы захотите сохранить это в массиве для дальнейшей обработки. Например, сохраните это в test.sh
:
#!/usr/bin/env bash
foo()
{
declare -a command=("$0")
for param in "$@"
do
command+=("$(printf %q "$param")")
done
echo "${command[@]}"
}
foo "$@"
При запуске ./test.sh "first argument" "second argument"
он должен вернуть:
./test.sh first\ argument second\ argument
Какие эквивалентные звонки.
BASH_COMMAND
переменная, но она, кажется, не пригодится ни в коем случае, кроме использования в ловушках.
some-command
сценарий оболочки, и он терпит неудачу. У меня будет ненулевой статус $?
, будет ли "нет" все еще сохраняться для существования переменной хранения some-command
?
DEBUG
Ловушка позволяет выполнить команду прямо перед любым простым выполнением команды. Строковая версия команды для выполнения (со словами, разделенными пробелами) доступна в BASH_COMMAND
переменной.
trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
…
echo "last command is $previous_command"
Обратите внимание, что это previous_command
будет меняться при каждом запуске команды, поэтому сохраните ее в переменной, чтобы использовать ее. Если вы также хотите узнать статус возврата предыдущей команды, сохраните обе в одной команде.
cmd=$previous_command ret=$?
if [ $ret -ne 0 ]; then echo "$cmd failed with error code $ret"; fi
Если вы хотите отменить только неудачные команды, используйте, set -e
чтобы ваш скрипт завершился с первой неудачной командой. Вы можете отобразить последнюю команду из EXIT
ловушки .
set -e
trap 'echo "exit $? due to $previous_command"' EXIT
Альтернативный подход, который может работать для некоторых целей, заключается в том, set -x
чтобы распечатать трассировку выполнения скрипта и изучить последние несколько строк трассировки.
Я считаю необходимым найти последнюю неудачную команду при наличии set -e
и set -o pipefail
опций, так как в противном случае bash просто прерывается без обратной связи о причине, поэтому я нашел, что это работает хорошо:
#!/usr/bin/env bash
set -eu
set -o pipefail
cur_command=
first_err_command=
first_err_lineno=
# This trap is executed in exactly the same conditions in which the `set -e` results in an exit.
trap 'cur_command=$BASH_COMMAND;
if [[ -z "$first_err_command" ]]; then
first_err_command=$cur_command;
first_err_lineno=$LINENO;
fi' ERR
trap 'if [[ ! -z "$first_err_command" ]]; then
echo "ERROR: Aborting at line: $first_err_lineno on command: $first_err_command";
fi' EXIT
echo "The following command causes bash to abort, but it should also result in a nice message"
false
echo "This message is not expected"
Если вы запустите вышеприведенное, вы увидите вывод ниже:
The following command causes bash to abort, but it should also result in a nice message
ERROR: Aborting at line: 22 on command: false
Номер строки не всегда может быть точным, но он должен дать вам что-то достаточно близкое, чтобы быть полезным.