Я хочу перебрать вывод команды без создания вложенной оболочки или использования временного файла.
Начальная версия моего скрипта выглядела так, но это не работает, так как создает подоболочку, и exit
команда завершает подоболочку вместо основного скрипта, который требуется. Это часть гораздо большего сценария для настройки политики маршрутизации, и он останавливает выполнение, если обнаруживает условие, которое приведет к сбою маршрутизации.
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
Поэтому одна из предложенных альтернатив - использовать такую команду, чтобы избежать подоболочки.
while read BLAH ; do echo $BLAH; done </root/regularfile
Поэтому мне кажется, что я также должен иметь возможность использовать такую команду, чтобы избежать подоболочки и при этом получить результат от программы, которую я хочу.
while read BLAH ; do echo $BLAH; done <(sysctl -a 2>/dev/null | grep '\.rp_filter')
К сожалению, использование этой команды приводит к этой ошибке.
-bash: syntax error near unexpected token `<(sysct ...
Я действительно запутался, так как это работает.
cat <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Я мог бы сохранить вывод этой команды во временный файл и использовать перенаправление на временный файл, но я хотел избежать этого.
Так почему же перенаправление дает мне ошибку, и у меня есть какие-либо варианты, кроме создания временного файла?
источник
Ответы:
Вы пропустили
<
. Должно быть:Думайте о
<(sysctl -a 2>/dev/null | grep '\.rp_filter')
том, чтобы быть файлом.источник
<(
в руководстве по bash (оно находится в разделе «процесс подстановки»).Еще несколько вариантов, если кто-нибудь придет сюда снова ...
В зависимости от оболочки, вы можете использовать
set -o errexit
родительскую оболочку для выхода, когда команда (включая подоболочку) завершает работу с ненулевым значением, не будучи пойманным вif
блоке или в конце&&
или||
, как вИли вы могли бы использовать подоболочку, чтобы сообщить родителю, используя kill и переменную среды $ PPID, если она доступна.
Или вы можете переместить блок while в функцию и вернуть 0/1 (явно возвращать 0 после блока while) и просто сделать свой конвейер как
sysctl | grep | function || exit
. Я полагаю, вы могли бы также поместить возвраты во встроенный блок, но функции - ваш друг. ;)источник