Ich möchte, dass meine Shell-Skripte immer dann fehlschlagen, wenn ein mit ihnen ausgeführter Befehl fehlschlägt.
Normalerweise mache ich das mit:
set -e
set -o pipefail
(normalerweise füge ich set -u
auch hinzu)
Die Sache ist, dass keines der oben genannten Verfahren mit Prozessersetzung funktioniert. Dieser Code gibt "ok" aus und beendet mit Returncode = 0, während ich möchte, dass es fehlschlägt:
#!/bin/bash -e
set -o pipefail
cat <(false) <(echo ok)
Gibt es etwas, das "Pipefail" entspricht, außer der Prozessersetzung? Gibt es eine andere Möglichkeit, die Ausgabe von Befehlen als Dateien an einen Befehl zu übergeben, aber einen Fehler auszulösen, wenn eines dieser Programme fehlschlägt?
Die Lösung eines armen Mannes wäre zu erkennen, ob diese Befehle in stderr schreiben (aber einige Befehle schreiben in erfolgreichen Szenarien in stderr).
Eine andere Lösung, die mehr mit Posix kompatibel ist, wäre die Verwendung von Named Pipes, aber ich muss diese Befehle, die Prozessersetzung verwenden, starten, da Oneliners aus kompiliertem Code automatisch erstellt werden. Das Erstellen von Named Pipes würde die Dinge komplizieren (zusätzliche Befehle, Überfüllungsfehler für Löschen usw.)
$$
funktioniert die Ersetzung bei mir nicht, da diese Befehlsersetzung nicht erfolgt, da der Befehl, der die Prozessersetzung verwendet, in einer Befehlspipeline ausgeführt wird, die aus einem "Nicht-Shell" -Code (Python) stammt. Wahrscheinlich sollte ich einen Unterprozess in Python erstellen und programmgesteuert weiterleiten.
kill -2 0
.
mkfifo pipe; { rm pipe; cat <file; } >pipe
. Dieser Befehl bleibt so lange hängen, bis ein Reader geöffnet wird,pipe
da dies die Shell ausführt.open()
Sobald sich ein Readerpipe
im fs-Link fürpipe
befindetrm
, wird diecat
Datei in den Deskriptor der Shell für diese Pipe kopiert. Und überhaupt, wenn Sie einen Fehler aus einem Prozessunter propagieren wollen tun: <( ! : || kill -2 "$$")