Ich versuche mit diesem Befehl das letzte Änderungsdatum einer Datei abzurufen
TM_LOCAL=`ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'`
TM_LOCAL hat nach Ausführung dieser Zeile den Wert "2012-05-16 23:18"
Ich möchte auch PIPESTATUS überprüfen, um festzustellen, ob ein Fehler aufgetreten ist. Wenn die Datei beispielsweise nicht vorhanden ist, wird ls
2 zurückgegeben. Sie $?
hat jedoch den Wert 0, da sie den Rückgabewert von hat awk
.
Wenn ich diesen Befehl alleine ausführe, kann ich den Rückgabewert von ls anhand von überprüfen ${PIPESTATUS[0]}
ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'
Funktioniert aber $PIPESTATUS
nicht wie erwartet, wenn ich die Ausgabe wie im ersten Beispiel einer Variablen zuordne. In diesem Fall hat das $PIPESTATUS
Array nur 1 Element, das dem entspricht$?
Die Frage ist also, wie ich beides bekommen $PIPESTATUS
und die Ausgabe gleichzeitig einer Variablen zuweisen kann.
Verwenden Sie
set -o pipefail
inbash
, um den am weitesten rechts liegenden Exit-Code ungleich Null in einer Pipeline-Befehlssequenz als abzurufen$?
. Vonman bash
:Dann können Sie einfach darauf zugreifen
$?
. Verwenden Sieset +o pipefail
wieder zu deaktivieren.quelle
Ich gehe davon aus, dass das Problem hier ist, dass PIPESTATUS vollständig verschwindet, sobald Sie einen Befehl ausführen. Sie können das komplette PIPESTATUS-Array in Bash-Version 2 oder höher folgendermaßen erhalten:
Dann Zugang
${status[0]}
,${status[1]}
etc.quelle
Das Hauptproblem bei "Was Sie erwarten" ist, dass ein Befehl in Backquotes in einer Subshell ausgeführt wird.
$PIPESTATUS
existiert dort und der von mir zurückgegebene Status folgt den gleichen Regeln, als ob Sie eine einzelne ausführbare Datei (oder ein Shell-Skript) ausgeführt hätten. Der Status des Befehls backquote ist derawk
Status ganz rechts ( ).Um zu implementieren, was @ Daniel Beck gesagt hat, setzen Sie die
pipefail
Option in der Subshell folgendermaßen:TM_LOCAL=`set -o pipefail; ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'`
Jetzt ist der Status, der$?
danach gespeichert wird, der Status vonls
(wenn nicht Null).Ich denke jedoch, dass ein expliziter
if [ -f ~/.vimrc ];
... Test besser lesbar wäre.Sie können keine Ausgabe in eine Variable erhalten und
PIPESTATUS
ohne eine temporäre Datei für die erstere zurückgeben oder die letztere in eine Zeichenfolge umwandeln.quelle
Ich wollte nur dann eine E-Mail von cron senden, wenn der Exit-Status nicht Null war
Der Trick ist, dass Sie, um das Standard für das Ende der Pipeline zu erhalten, es in eine Subshell einfügen müssen - aber das scheint den PIPESTATUS-Wert zu verbergen ...
Test Cron spuckt etwas Ausgabe aus und beendet mit 1 oder 0 ..
UPDATE: Der PIPESTATUS ist erst sichtbar, wenn der Pipeline-Befehl verarbeitet wird
quelle
Eine Möglichkeit besteht darin, die Existenz Ihrer Datei zu überprüfen, bevor Sie die Änderungszeit mit einem Aufruf von erhalten
stat
. Dastat
im Zeitstempel etwas mehr zurückgegeben wird, als Sie möchten, können Sie ihn mithilfe der Parametererweiterung zuschneiden.Mit GNU
stat
(z. B. unter Linux) können Sie Folgendes ausführen:Unter Mac OS X und anderen BSD-Systemen unterscheidet sich die
stat
Syntax und kann ein Zeitformat angeben:quelle
$TM_LOCAL
sicher ist. Es ist nur dann sicher, wenn Sie erwartet haben, dass es keinen vorherigen Wert hat. Angenommen, der Wert war zuvor2020-02-27 17:14
und es gibt keine~/.vimrc
Datei. Das hättest du dann2020-02-27 17
. Ich würde diese beiden Zeilen daher mit einer zusätzlichen&&
Zeilengruppe verketten oder (vorzugsweise, da dies nicht so gut lesbar ist) eineif
Zeilengruppe verwenden.