Os idiomas `set -e` e` grep` para impedir a saída prematura do shell script quando o padrão não for encontrado

15

Ajuda necessária - no contexto de script de shell em um bash GNU / LINUX:

Eu sempre uso set -e. Muitas vezes, eu gostaria grepe nem sempre quero que o script encerre a execução se greptiver um status de saída do 1padrão de indicação não encontrado.

Algumas coisas que tentei resolver esse problema são as seguintes:

(Tente I)
Se set +o pipefaile invocar o grep com algo como, grep 'p' | wc -lentão, obtenho o comportamento desejado até que um futuro mantenedor o permita pipefail. Além disso, gosto de ativar, pipefailpara que isso não funcione para mim.

(Tente II)
Use um sedou awkapenas o padrão de linhas de impressão correspondente e depois as wclinhas correspondentes para testar o padrão correspondente. Não gosto dessa opção porque usar o sedpara grepparece uma solução alternativa para o meu verdadeiro problema.

(Tente III)
Este é o meu menos favorito - algo como:set +e; grep 'p'; set-e

Qualquer insight / idioma seria muito apreciado - obrigado.

Yeow_Meng
fonte

Respostas:

19

Você pode colocar o grep em uma ifcondição ou, se não se importar com o status de saída, adicione || true.

Exemplo: grepmata o shell

$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233

solução 1: descarte o status de saída diferente de zero

$ bash
$ set -e
$ echo $$
34074
$ grep foo /etc/motd || true
$ echo $$
34074

solução 2: testar explicitamente o status de saída

$ if ! grep foo /etc/motd; then echo not found; fi
not found
$ echo $$
34074

Na página do man bash discutindo set -e:

O shell não sair se o comando que não faz parte da lista de comando imediatamente após um enquanto ou até palavras-chave, parte do teste seguindo as se ou elif palavras reservadas, parte de qualquer comando executado em um && ou ││ lista, exceto o comando após o final && ou ││ , qualquer comando em um pipeline, exceto o último, ou se o valor de retorno do comando estiver sendo invertido com ! .

Glenn Jackman
fonte
Dado que o bash por um longo tempo não implementou -e corretamente, pode ser que a documentação ainda não esteja correta. Como o texto parece idêntico à página de manual do bash-3.x, observe: todas as versões do bash anteriores ao bash4.0 foram implementadas -e incorretamente.
Schily
Observe também que como o padrão POSIX estava errado assim, mudamos o texto POSIX para lidar com -e em 2009 erro
Schily
1
@schily Por favor, indique onde se pode descobrir qual é o comportamento 'correto' de -e, o que o bash <4 fez de maneira diferente e o que foi alterado no POSIX.
Zwol 9/10/2015
Os bugs no bash-3 basicamente o tornam inutilizável make, pois nem sempre sai por erros. Para as discussões POSIX relacionados, você pode gostar de verificar austingroupbugs.net
Schily
@schily Você poderia, por favor, ser mais específico?
Zwol 9/10/2015