O que é essa sintaxe no final de um loop while?

0

No seguinte código de script BASH:

while read -r line
do
    if [some_condition]; then
        do_thing1
        do_thing2
        continue
    fi
done < $SOME_VAR

Qual é o significado da última linha? Especificamente, o que está sendo feito com o valor de $ SOME_VAR?

    
por Anonymous Human 30.01.2018 / 18:10

4 respostas

4

O < é o operador de redirecionamento de entrada, $SOME_VAR provavelmente contém o nome de um arquivo. Juntos, eles faziam o loop ler as linhas do arquivo.

    
por 30.01.2018 / 18:11
2

< é o operador indireto do shell. Ele pega o arquivo fornecido e o usa como entrada padrão para o comando anterior. Esse comando seria mais ou menos análogo a:

cat $SOME_VAR | while read -r line; do
  if stuff; then
     consequence
  else
     otherstuff
  fi
done

Se SOME_VAR não fosse atribuído a um arquivo no diretório de trabalho atual (ou o caminho completo para um arquivo), o shell lançaria um erro No such file or directory .

    
por 30.01.2018 / 18:12
1

As outras duas respostas já cobriram a maioria dos aspectos. Eu gostaria de acrescentar que, para entender essa sintaxe, você deve interpretar o while ... done como uma declaração única, mas complexa, e $SOME_VAR é alimentado para esta declaração como stdin . Ele será consumido sempre que houver necessidade de ler stdin . Nesse caso, a instrução read . Na verdade, não há diferença com a sintaxe cmd <in >out padrão.

    
por 30.01.2018 / 18:22
1

Em termos muito curtos, < redireciona arquivo especificado à direita do símbolo < para stdin stream de qualquer comando ou grupo de comandos que você esteja executando.

O while read -r line; do...done < input.txt é a maneira padrão de ler um arquivo linha por linha . Embora, é claro, $SOME_VAR não precise ser um arquivo de texto - pode ser chamado de pipe entre outras coisas - essa é a maneira usual e é usada para evitar problemas com a divisão de palavras no shell.

Geralmente novos no shell script acham que podem fazer algo como for line in $(cat file.txt) , mas se cada linha tiver várias palavras separadas por espaços, o loop for processará cada palavra em vez de cada linha. Algo parecido com isto:

$ for i in $(cat input.txt); do echo "$i" ; done
one
two
three
four

Isso não é bom. Por outro lado, o loop permite processar toda a linha sem problemas.

$ while read -r line; do echo "$line" ;done < input.txt
one two
three four

Você pode estar se perguntando por que não usar apenas cat | while read -r line... , mas esse é um processo extra e uso inútil do gato .

O redirecionamento no fluxo de stdin de um loop pode ser feito com outras coisas também. Se você estiver usando bash que suporta <<< , você pode enviar uma string literal de texto para seu loop while.

while read -r line;do
    # do something with line
done <<< "Hello World"

Um exemplo redundante? Sim, mas prova que essa sintaxe é mais sobre o redirecionamento de entrada para o loop while.

Veja também:

por 30.01.2018 / 18:39