Usando grep com pipe ee comercial para filtrar erros da localização

22

Estou usando o cygwin para encontrar um arquivo no cygdrive.

No entanto, preciso suprimir as mensagens de permissão negada (caso contrário, os resultados serão ocultos nas mensagens de erro). O seguinte comando funciona:

find -name 'myfile.*' |& grep -v "Permission denied"

Não entendo por que o e comercial precisa ser colocado nesse comando; ele esperaria que isso funcionasse, mas não.

find -name 'myfile.*' | grep -v "Permission denied"

Por favor, explique o significado do e comercial.

Henrik K
fonte

Respostas:

24

Nos sistemas tipo Unix, existem dois caminhos de saída que, se não modificados, enviarão a saída para sua tela. Erro padrão (ou stderr) é aquele que captura a maioria das falhas e condições de erro.

Para passar a mensagem de permissão negada no stderr para o mesmo fluxo de saída que "saída regular", você deve combinar os dois. No seu exemplo, para que você grep -vopere corretamente, você combina stdout (saída padrão) e stderr com a sintaxe arcana que vê.

Na seção do manual do GNU Bash, seção 3.2.2 Pipelines :

Se ' |&' é utilizado, comando1 é o erro padrão, para além da sua saída padrão, está ligado a comando2 de entrada padrão através do tubo; é uma abreviação de 2>&1 |. Esse redirecionamento implícito do erro padrão para a saída padrão é executado após qualquer redirecionamento especificado pelo comando.

Além disso, como geirha aponta, se você quiser se livrar da saída stderr, faça algo como

find -name 'myfile.*' 2> /dev/null

ou talvez

find -name 'myfile.*' 2> /tmp/errorlog

E observe que, se você tiver cadeias de comandos, como findpassar sua saída para xargsvocê, precisará colocar todo o pipeline de comandos entre parênteses para capturar a saída de todos os componentes do comando. Por exemplo,

(find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 )  2> /dev/null

Se você deixou de fora os parênteses, e fez isso em vez disso -

find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 2> /dev/null

você ainda verá erros de permissão negados na localização ou no egrep, mas o stderr será redirecionado para xargs.

Como você viu, provavelmente jogaria fora o stderr somente depois de visualizar seu conteúdo durante uma execução de teste.

Observe que, com o GNU finde até onde eu sei, qualquer compatível com POSIX find, a -printopção está implícita. Você ainda pode fornecê-lo explicitamente, se quiser.

belacqua
fonte
Parece ser apenas bash4 + wiki.bash-hackers.org/bash4#redirection
Luke Exton
1
@LukeExton Sim. Em outros shells, 2>&1 |pode ser usado no lugar de |&(ou seja, é possível redirecionar explicitamente o stderr para o stdout e depois direcioná-lo para o próximo comando no pipeline).
Eliah Kagan
2> >( grep filter )também é útil
user1133275 14/08
1

Se você deseja ignorar as mensagens de erro, basta redirecionar o stderr para / dev / null.

find . -name 'myfile.*' -print 2>/dev/null

Além disso, considere ler http://mywiki.wooledge.org/UsingFind .

Geirha
fonte