grep -v comportamento inesperado

4

Digamos que eu tenha um script estúpido simples que remova arquivos finalizando, assim:

rm *.uvw *.xyz

O script, ou rm , para ser preciso, escreve mensagens no stderr se não puder encontrar pelo menos um arquivo com o final especificado.

Agora vamos dizer que o script é um pouco maior e faz um pouco mais com um pouco mais de tipos de arquivo e eu não estou interessado em quais tipos de arquivos existem e quais não, mas as reclamações sobre os tipos de arquivos inexistentes obstruem o resto das mensagens de saída e erro que eu estou mais interessado, então eu quero filtrar a saída:

rm *.uvw *.xyz 2>&1 | grep -v "No such file or directory"

Isso funciona bem na maior parte, mas remove a parte da mensagem dos diálogos interativos, que, por exemplo, perguntam, se um arquivo protegido contra gravação deve ser excluído, então eu sou solicitado sem a mensagem correspondente.

Eu não entendo esse comportamento e não encontrei nenhuma informação relacionada. Alguém pode explicar isso?

    
por Wanderer 07.08.2016 / 18:36

2 respostas

10

O problema

Quando o rm solicitar o uso da entrada, ele não colocará uma nova linha no final do prompt:

$ rm *.uvw *.xyz
rm: remove write-protected regular empty file 'a.xyz'?

grep é baseado em linha. Só pode processar linhas completas. Não pode dizer se a linha deve ser impressa até que a linha esteja completa. Assim, utilitários padrão para lidar com buffering, como stdbuf , não podem ajudar.

A solução

Use nullglob e remova as mensagens de arquivos ausentes.

Sem nullglob, as mensagens que você não deseja aparecem:

$ rm *.uvw *.xyz
rm: cannot remove '*.uvw': No such file or directory
rm: remove write-protected regular empty file 'a.xyz'? n

Com isso, a mensagem "Nenhum arquivo ou diretório" é suprimida:

$ shopt -s nullglob
$ rm *.uvw *.xyz
rm: remove write-protected regular empty file 'a.xyz'? n

Refinamento

Se não houver nenhum arquivo que corresponda a glob, uma mensagem de erro diferente será exibida:

$ shopt -s nullglob
$ rm *.uvw *.xyz
rm: missing operand
Try 'rm --help' for more information.

Uma maneira simples de evitar isso é certificar-se de que pelo menos um desses arquivos exista:

shopt -s nullglob
[ -e "deleteme.xyz" ] ||touch deleteme.xyz
rm *.uvw *.xyz

Como deleteme.xyz será apagado de qualquer forma, não há problema em tocá-lo antes de executarmos rm .

    
por 07.08.2016 / 18:45
1

Se você estiver usando o GNU grep, veja a opção '-s' para suprimir mensagens.

-s, --no-messages
    Suppress error messages about nonexistent or unreadable files.

*** Nota: esta não é uma opção portátil.

    
por 09.08.2016 / 20:47

Tags