Chcę zapętlić wynik polecenia bez tworzenia podpowłoki lub korzystania z pliku tymczasowego.
Początkowa wersja mojego skryptu wyglądała tak, ale to nie działa, ponieważ tworzy podpowłokę, a exit
polecenie kończy podpowłokę zamiast wymaganego skryptu głównego. Jest to część znacznie większego skryptu służącego do konfigurowania routingu zasad i wstrzymuje wykonanie, jeśli wykryje warunek, który spowoduje, że routing się nie powiedzie.
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
Jedną z sugerowanych alternatyw jest użycie takiego polecenia, aby uniknąć podpowłoki.
while read BLAH ; do echo $BLAH; done </root/regularfile
Wydaje mi się więc, że powinienem także móc użyć takiego polecenia, aby uniknąć podpowłoki i nadal otrzymywać dane wyjściowe z programu, który chcę.
while read BLAH ; do echo $BLAH; done <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Niestety użycie tego polecenia powoduje ten błąd.
-bash: syntax error near unexpected token `<(sysct ...
Jestem naprawdę zdezorientowany, ponieważ to działa.
cat <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Mogłem zapisać dane wyjściowe tego polecenia w pliku tymczasowym i użyć przekierowania w pliku tymczasowym, ale chciałem tego uniknąć.
Dlaczego więc przekierowanie powoduje błąd i czy mam inne opcje niż utworzenie pliku tymczasowego?
źródło
Odpowiedzi:
Przegapiłeś a
<
. Powinien być:Pomyśl o
<(sysctl -a 2>/dev/null | grep '\.rp_filter')
byciu plikiem.źródło
<(
w podręczniku bash (znajduje się pod „substytucją procesu”).Jeszcze kilka alternatyw, jeśli ktoś tu jeszcze przyjdzie ...
W zależności od powłoki można prawdopodobnie użyć
set -o errexit
wyjścia powłoki nadrzędnej, gdy polecenie (w tym podpowłoka) kończy się na niezerową, bez uwięzienia wif
bloku lub końcowym,&&
lub||
, jak wLub, możesz mieć sygnał podpowłoki nadrzędny za pomocą kill i zmienną środowiskową $ PPID, jeśli jest dostępna.
Lub możesz przenieść blok while do funkcji i zwrócić 0/1 (jawnie zwrócić 0 po bloku while) i po prostu zrobić swój potok jak
sysctl | grep | function || exit
. Przypuszczam, że możesz również wstawić zwroty do bloku wbudowanego, ale funkcje są twoim przyjacielem. ;)źródło