Você perdeu um <
. Deve ser:
while read BLAH ; do echo $BLAH; done < <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Pense em <(sysctl -a 2>/dev/null | grep '\.rp_filter')
como um arquivo.
Eu quero repetir a saída de um comando sem criar um sub-shell ou usar um arquivo temporário.
A versão inicial do meu script ficou assim, mas isso não funciona, pois cria um subshell, e o comando exit
finaliza o subshell em vez do script principal, que é necessário. Ele faz parte de um script muito maior para configurar o roteamento de políticas e interrompe a execução se detectar uma condição que causará falha no roteamento.
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
Então, uma das alternativas sugeridas é usar um comando como esse para evitar a sub-camada.
while read BLAH ; do echo $BLAH; done </root/regularfile
Então, parece-me que eu também deveria poder usar um comando como esse para evitar o subshell e ainda obter a saída do programa que eu quero.
while read BLAH ; do echo $BLAH; done <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Infelizmente, o uso desse comando resulta nesse erro.
-bash: syntax error near unexpected token '<(sysct ...
Eu fico realmente confuso, pois isso funciona.
cat <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Eu poderia salvar a saída desse comando em um arquivo temporário e usar o redirecionamento no arquivo temporário, mas queria evitar fazer isso.
Então, por que o redirecionamento está me dando um erro, e eu tenho outras opções além de criar um arquivo temporário?
Para mais algumas alternativas, se alguém vier aqui de novo ...
Dependendo do shell, você provavelmente pode usar set -o errexit
para que o shell pai seja encerrado quando um comando (incluindo um subshell) sair diferente de zero sem ficar preso em um bloco if
ou em um &&
ou% final||
, como em
/bin/false || echo "ignoring error"
Ou, você pode fazer com que o subshell sinalize o pai usando kill e a variável de ambiente $ PPID, se disponível.
Ou você poderia mover o bloco while para uma função e retornar 0/1 (explicitamente retornar 0 após o bloco while) e apenas fazer o seu pipeline como sysctl | grep | function || exit
. Eu suponho que você poderia colocar os retornos no bloco inline, também, mas as funções são suas amigas. ;)
Tags bash scripting io-redirection