Antworten:
Verwenden Sie fc
diese Option , um die vorherige Befehlszeile abzurufen. Es wird normalerweise verwendet, um die vorherige Befehlszeile in Ihrem bevorzugten Editor zu bearbeiten, hat aber auch einen "Listen" -Modus:
last_command="$(fc -nl -1)"
caller
und der Bash - Arrays BASH_LINENO
, BASH_SOURCE
und FUNCNAME
eine Art von Stack - Trace zu tun.
Wenn der letzte Befehl ohne Argumente ausgeführt wurde, wird er in der $_
Variablen gespeichert . Dies enthält normalerweise das letzte Argument des vorherigen Befehls. Wenn also keine Argumente vorhanden waren, ist der Wert von $_
der letzte Befehl selbst.
Eine andere Möglichkeit besteht darin, die Details des letzten Hintergrundbefehls zu erfahren . Wie l0b0 schrieb, $!
hält seine PID - so können Sie die Ausgabe von analysieren ps $!
(möglicherweise mit zusätzlichen Formatierungsoptionen zu ps
).
Nein, aber Sie können es während der Ausführung zum Speichern für andere Befehle erhalten:
$0
: Pfad des aktuellen Shell-Skripts.$FUNCNAME
: "Name der aktuellen Funktion.""$@"
: Alle Parameter des aktuellen Befehls werden separat angegeben.$!
: "PID (Prozess-ID) des letzten im Hintergrund ausgeführten Jobs."$$
: "Prozess-ID (PID) des Skripts selbst."Der vollständige Befehl des aktuellen Skripts sollte daher lauten "$0" "$@"
. Wenn es eine Funktion ist, sollte es sein "$FUNCNAME" "$@"
. Möglicherweise möchten Sie dies für die zukünftige Verarbeitung in einem Array speichern. Speichern Sie dies beispielsweise in test.sh
:
#!/usr/bin/env bash
foo()
{
declare -a command=("$0")
for param in "$@"
do
command+=("$(printf %q "$param")")
done
echo "${command[@]}"
}
foo "$@"
Beim Ausführen ./test.sh "first argument" "second argument"
sollte Folgendes zurückgegeben werden:
./test.sh first\ argument second\ argument
Welches sind gleichwertige Anrufe.
BASH_COMMAND
Variable, die aber abgesehen von der Verwendung in Fallen in keiner Weise nützlich zu sein scheint.
some-command
in einem Shell-Skript ausgeführt werde und es fehlschlägt ? Ich habe einen Status ungleich Null in $?
. Wird "Nein" immer noch für das Vorhandensein von variablem Halten gelten some-command
?
Mit dem DEBUG
Trap können Sie einen Befehl unmittelbar vor einer einfachen Befehlsausführung ausführen. In der BASH_COMMAND
Variablen ist eine Zeichenfolgenversion des auszuführenden Befehls (mit durch Leerzeichen getrennten Wörtern) verfügbar .
trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
…
echo "last command is $previous_command"
Beachten Sie, dass previous_command
sich dies jedes Mal ändert, wenn Sie einen Befehl ausführen. Speichern Sie ihn daher in einer Variablen, um ihn zu verwenden. Wenn Sie auch den Rückgabestatus des vorherigen Befehls wissen möchten, speichern Sie beide in einem einzigen Befehl.
cmd=$previous_command ret=$?
if [ $ret -ne 0 ]; then echo "$cmd failed with error code $ret"; fi
Wenn Sie nur bei fehlgeschlagenen Befehlen abbrechen möchten, verwenden Sie diese Option set -e
, um das Skript beim ersten fehlgeschlagenen Befehl zu beenden. Sie können den letzten Befehl aus der EXIT
Trap anzeigen .
set -e
trap 'echo "exit $? due to $previous_command"' EXIT
Ein alternativer Ansatz, der für einige Verwendungszwecke geeignet sein könnte, besteht darin set -x
, eine Ablaufverfolgung der Skriptausführung zu drucken und die letzten Zeilen der Ablaufverfolgung zu untersuchen.
Ich finde es wichtig, den letzten fehlgeschlagenen Befehl zu finden, wenn ich set -e
und set -o pipefail
Optionen habe, da sonst bash einfach abgebrochen wird, ohne Rückmeldung darüber, warum. Deshalb habe ich festgestellt, dass dies gut funktioniert:
#!/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"
Wenn Sie die oben genannten Schritte ausführen, wird am Ende die folgende Ausgabe angezeigt:
The following command causes bash to abort, but it should also result in a nice message
ERROR: Aborting at line: 22 on command: false
Die Zeilennummer ist möglicherweise nicht immer genau, sollte Ihnen jedoch nahe genug sein, um nützlich zu sein.