Evitando erros devido ao asterisco não expandido


16

No bash, costumo usar for-loops, como os seguintes

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

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

Respostas:


20

Sim, execute o seguinte comando:

shopt -s nullglob

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

  • Se você deseja esse comportamento por padrão, adicione o comando no seu ~/.bashrc
  • Se você deseja detectar um globo nulo no shell POSIX, tente

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

Veja http://mywiki.wooledge.org/NullGlob


11
Observe que é realmente possível ter um arquivo chamado *.txt. Valeria a pena verificar se o arquivo existe.
Chris Baixo

post editado de acordo.
Gilles Quenot

@ChrisDown Observe que o mesmo comentário da sua resposta se aplica aqui (com consequências potencialmente mais graves por causa do que em breakvez de continue).
Stéphane Chazelas

6

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

Em cartuchos 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" ] || continuecomo primeira parte do seu forloop.


11
Observe que não seria estritamente equivalente, pois [ -eretornaria false para arquivos inacessíveis ou arquivos que são links simbólicos para arquivos inacessíveis ou inexistentes.
Stéphane Chazelas

@StephaneChazelas, deixe que os pontos sobre links simbólicos sejam reconhecidos. Mas o que você tem em mente por "arquivos inacessíveis"? Mesmo que eu chmod 0 the_file, [ -e the_file ]ainda avalia verdade, por isso deve ser outra coisa.
dubiousjim

11
edição enviada para lidar com links simbólicos quebrados. espero que esteja tudo bem.
dubiousjim

2
@dubiousjim mkdir -p x/{a,b} && chmod 444 x && echo x/* && [ -e x/a ],. x / a está inacessível, mas como x é legível x / * será expandido.
Stéphane Chazelas

@StephaneChazelas, ótimo, obrigado por explicar.
dubiousjim

4

A técnica usual para conchas que não têm nullglobopção é

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

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

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

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


0

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

Isso remove completamente o forloop e o brilho da concha da equação. findexecutará o -execcomando uma vez por partida e, se não houver correspondências, nunca será executado. Os -maxdepth 0instrutores descobrem que não se recursão em subdiretórios do caminho-argumento nomeado (. , neste caso).

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.