Ich möchte die Ausgabe eines Befehls durchlaufen, ohne eine Unter-Shell zu erstellen oder eine temporäre Datei zu verwenden.
Die ursprüngliche Version meines Skripts sah folgendermaßen aus, funktioniert jedoch nicht, da eine Unterschale erstellt wird und der exit
Befehl die Unterschale anstelle des erforderlichen Hauptskripts beendet. Es ist Teil eines viel größeren Skripts zum Konfigurieren des Richtlinienroutings und stoppt die Ausführung, wenn eine Bedingung erkannt wird, die dazu führt, dass das Routing fehlschlägt.
sysctl -a 2>/dev/null | grep '\.rp_filter' | while read -r -a RPSTAT ; do
if [[ "0" != "${RPSTAT[2]}" ]] ; then
echo >&2 "RP Filter must be disabled on all interfaces!"
echo >&2 "The RP filter feature is incompatible with policy routing"
exit 1
fi
done
Eine der vorgeschlagenen Alternativen besteht darin, einen solchen Befehl zu verwenden, um die Unterschale zu vermeiden.
while read BLAH ; do echo $BLAH; done </root/regularfile
Daher scheint es mir, dass ich auch einen solchen Befehl verwenden sollte, um die Subshell zu vermeiden und trotzdem die Ausgabe des gewünschten Programms zu erhalten.
while read BLAH ; do echo $BLAH; done <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Leider führt die Verwendung dieses Befehls zu diesem Fehler.
-bash: syntax error near unexpected token `<(sysct ...
Ich bin wirklich verwirrt, da dies funktioniert.
cat <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Ich könnte die Ausgabe dieses Befehls in einer temporären Datei speichern und die Umleitung für die temporäre Datei verwenden, aber ich wollte das vermeiden.
Warum gibt mir die Umleitung einen Fehler und habe ich andere Optionen als das Erstellen einer temporären Datei?
quelle
Antworten:
Du hast einen verpasst
<
. Sollte sein:Denken Sie
<(sysctl -a 2>/dev/null | grep '\.rp_filter')
daran, eine Datei zu sein.quelle
<(
im Bash-Handbuch suchen (unter "Prozessersetzung").Für ein paar weitere Alternativen, wenn jemand wieder hierher kommt ...
Abhängig von der Shell können Sie wahrscheinlich
set -o errexit
die übergeordnete Shell beenden lassen, wenn ein Befehl (einschließlich einer Subshell) ungleich Null beendet wird, ohne in einemif
Block oder einem nachgestellten&&
oder||
wie in eingeschlossen zu seinSie können auch festlegen, dass die Unterschale dem übergeordneten Element mithilfe von kill und der Umgebungsvariablen $ PPID signalisiert, sofern verfügbar.
Oder Sie können den while-Block in eine Funktion verschieben und 0/1 zurückgeben (explizit 0 nach dem while-Block zurückgeben) und einfach Ihre Pipeline wie folgt ausführen
sysctl | grep | function || exit
. Ich nehme an, Sie könnten die Rückgaben auch in den Inline-Block einfügen, aber Funktionen sind Ihr Freund. ;)quelle