Risposte:
Utilizzare fcper ottenere la riga di comando precedente. Viene normalmente utilizzato per modificare la precedente riga di comando nel tuo editor preferito, ma ha anche una modalità "elenco":
last_command="$(fc -nl -1)"
callere gli array bash BASH_LINENO, BASH_SOURCEe FUNCNAMEdi fare una sorta di traccia dello stack.
Se l'ultimo comando è stato eseguito senza argomenti, verrà salvato nella $_variabile. Normalmente contiene l' ultimo argomento del comando precedente, quindi se non c'erano argomenti, il valore di $_è l'ultimo comando stesso.
Un'altra opzione è imparare i dettagli dell'ultimo comando in background . Come ha scritto l0b0, $!contiene il suo PID, in modo da poter analizzare l'output di ps $!(possibilmente con opzioni di formattazione aggiuntive su ps).
No, ma è possibile ottenerlo durante l'esecuzione per memorizzare altri comandi:
$0: Percorso dello script di shell corrente.$FUNCNAME: "Nome della funzione corrente.""$@": Tutti i parametri del comando corrente, indicati separatamente.$!: "PID (ID processo) dell'ultimo lavoro eseguito in background."$$: "Process ID (PID) dello script stesso."Dovrebbe quindi essere il comando completo dello script corrente "$0" "$@". Se è una funzione dovrebbe essere "$FUNCNAME" "$@". Si consiglia di archiviarlo in un array per elaborazioni future. Ad esempio, memorizzalo in test.sh:
#!/usr/bin/env bash
foo()
{
declare -a command=("$0")
for param in "$@"
do
command+=("$(printf %q "$param")")
done
echo "${command[@]}"
}
foo "$@"
Durante l'esecuzione ./test.sh "first argument" "second argument", dovrebbe restituire:
./test.sh first\ argument second\ argument
Quali sono chiamate equivalenti.
BASH_COMMANDvariabile, ma non sembra essere utile in alcun modo, a parte l'uso nelle trappole.
some-commandin uno script di shell, e non riesce. Avrò uno stato diverso da zero $?, "no" rimarrà valido per l'esistenza di un mantenimento variabile some-command?
La DEBUGtrap consente di eseguire un comando subito prima di qualsiasi semplice esecuzione del comando. Nella BASH_COMMANDvariabile è disponibile una versione stringa del comando da eseguire (con parole separate da spazi) .
trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
…
echo "last command is $previous_command"
Nota che previous_commandcambierà ogni volta che esegui un comando, quindi salvalo in una variabile per usarlo. Se vuoi conoscere anche lo stato di ritorno del comando precedente, salva entrambi in un unico comando.
cmd=$previous_command ret=$?
if [ $ret -ne 0 ]; then echo "$cmd failed with error code $ret"; fi
Se si desidera interrompere solo comandi non riusciti, utilizzare set -eper far uscire lo script dal primo comando non riuscito. È possibile visualizzare l'ultimo comando dalla EXITtrap .
set -e
trap 'echo "exit $? due to $previous_command"' EXIT
Un approccio alternativo che potrebbe funzionare per alcuni usi è quello set -xdi stampare una traccia dell'esecuzione dello script ed esaminare le ultime righe della traccia.
Trovo essenziale trovare l'ultimo comando fallito quando si hanno set -ee le set -o pipefailopzioni, altrimenti Bash si interrompe semplicemente senza feedback sul perché, quindi questo è quello che ho trovato funzionante:
#!/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 esegui quanto sopra, finirai per vedere il seguente tipo di output:
The following command causes bash to abort, but it should also result in a nice message
ERROR: Aborting at line: 22 on command: false
Il numero di riga potrebbe non essere sempre preciso, ma dovrebbe darti qualcosa di abbastanza vicino per essere utile.