Evitar erros devido ao asterisco não expandido

15

No bash eu costumo usar loops for como o seguinte

for file in *.type; do 
  sommecommand "$file"; 
done;

para executar uma operação para todos os arquivos correspondentes a *.type . Se nenhum arquivo com este final for encontrado nos diretórios de trabalho, o asterisco não será expandido e, normalmente, receberei uma mensagem de erro dizendo que o somecommand não encontrou o arquivo. Eu posso pensar imediatamente em várias maneiras de evitar esse erro. Mas adicionar uma condicional não parece ser muito elegante. Existe uma maneira curta e limpa para conseguir isso?

    
por highsciguy 18.11.2012 / 20:05

4 respostas

19

Sim, execute o seguinte comando:

shopt -s nullglob

anula a correspondência e nenhum erro será acionado.

  • se você quiser esse comportamento por padrão, adicione o comando em ~/.bashrc
  • se você quiser detectar um glob nulo no shell POSIX, tente

    for i in *.txt; do
      [ "$i" = '*.txt' ] && [ ! -e '*.txt' ] && continue
    done
    

Veja o link

    
por 18.11.2012 / 20:08
5

No bash, você pode usar shopt -s nullglob para expandir para uma matriz vazia se não houver correspondências.

Em shells POSIX sem nullglob , você pode evitar esse problema verificando se o nome do arquivo que está sendo passado realmente existe tendo [ -e "$file" ] || [ -L "$file" ] || continue como a primeira parte do seu for loop.

    
por 18.11.2012 / 20:10
2

A técnica usual para shells que não possuem a opção nullglob é

set -- [*].type *.type
case $1$2 in
  '[*].type*.type') shift 2;;
  *) shift
esac
for file do
  cmd  -- "$file"
done

O [*].type extra é para cobrir o caso em que há um arquivo chamado *.type no diretório atual.

Agora, se você deseja incluir arquivos de ponto, se torna mais complicado .

Acredito que a técnica foi inventada por Laura Fairhead na usenet há alguns anos.

    
por 19.11.2012 / 10:59
0

find . -name '*.type' -maxdepth 0 -exec somecommand "{}" ";"

Isso remove o loop for e a globalização do shell da equação completamente. find executará o comando -exec uma vez por jogo e, se não houver correspondências, ele nunca será executado. O -maxdepth 0 instrui a localizar para não recursionar em subdiretórios do caminho-argumento nomeado ( . , neste caso).

A desvantagem é que envolve outro aplicativo, embora esteja presente em praticamente todos os sistemas Linux existentes (e provavelmente também na maioria dos Unixes).

    
por 19.11.2012 / 11:22