Use fc
para obter a linha de comando anterior. É normalmente usado para editar a linha de comando anterior em seu editor favorito, mas também tem um modo de "lista":
last_command="$(fc -nl -1)"
A variável $?
mantém o status de saída do último comando de execução. Existe uma variável que mantém o último comando de execução?
Se o último comando foi executado sem argumentos, ele será salvo na variável $_
. Isso normalmente contém o último argumento do comando anterior - assim, se não houver argumentos, o valor de $_
é o último comando em si.
Outra opção é aprender os detalhes do último comando background . Como l0b0 escreveu, $!
contém seu PID - assim você pode analisar a saída de ps $!
(possivelmente com opções adicionais de formatação para ps
).
Não, mas você pode obtê-lo durante a execução para armazenar outros comandos:
$0
: caminho do script de shell atual. $FUNCNAME
: "Nome da função atual". "$@"
: Todos os parâmetros do comando atual, citados separadamente. $!
: "PID (ID do processo) do último trabalho executado em segundo plano." $$
: "ID do processo (PID) do script em si." Portanto, o comando completo do script deve ser "$0" "$@"
. Se for uma função, deve ser "$FUNCNAME" "$@"
. Você pode querer armazenar isso em uma matriz para processamento futuro. Por exemplo, armazene isso em test.sh
:
#!/usr/bin/env bash
foo()
{
declare -a command=("$0")
for param in "$@"
do
command+=("$(printf %q "$param")")
done
echo "${command[@]}"
}
foo "$@"
Ao executar ./test.sh "first argument" "second argument"
, ele deve retornar:
./test.sh first\ argument second\ argument
Quais são chamadas equivalentes.
O DEBUG
trap permite que você execute um comando corretamente antes de qualquer execução simples de comando. Uma versão de string do comando para executar (com palavras separadas por espaços) está disponível no BASH_COMMAND
variável.
trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
…
echo "last command is $previous_command"
Observe que previous_command
mudará toda vez que você executar um comando, então salve-o em uma variável para usá-lo. Se você quiser saber o status de retorno do comando anterior, salve ambos em um único comando.
cmd=$previous_command ret=$?
if [ $ret -ne 0 ]; then echo "$cmd failed with error code $ret"; fi
Se você deseja apenas interromper os comandos com falha, use set -e
para fazer seu script sair no primeiro comando com falha. Você pode exibir o último comando da EXIT
trap .
set -e
trap 'echo "exit $? due to $previous_command"' EXIT
Uma abordagem alternativa que pode funcionar para alguns usos é usar set -x
para imprimir um traço da execução do script e examinar as últimas linhas do traço.
Acho essencial encontrar o último comando com falha ao ter as opções set -e
e set -o pipefail
, caso contrário, o bash simplesmente é cancelado sem comentários sobre o motivo, então é isso que achei funcionando bem:
#!/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"
Se você executar o acima, você verá o seguinte tipo de saída abaixo:
The following command causes bash to abort, but it should also result in a nice message
ERROR: Aborting at line: 22 on command: false
O número da linha pode nem sempre ser preciso, mas deve fornecer algo próximo o suficiente para ser útil.