Fornece redirecionamento para comandos usados em comandos compostos

1

Se eu quiser fornecer redirecionamento para entradas ou saídas ( < myfile ou > myfile ) para os comandos test-commands , consequent-commands , command1 e command2 em

if test-commands; then
consequent-commands;

until test-commands; do consequent-commands; done

while test-commands; do consequent-commands; done

command1 && command2

command1 || command2

onde devo colocar os redirecionamentos?

Por exemplo, vi

while read a; 
  do echo "$a"; 
done < myfile;

Gostaria de saber por que colocar < myfile depois de done , em vez de depois de read a ?

Isso também me faz pensar de maneira mais geral (como parte inicial deste post):

  • onde uma direção deve ser colocada para um comando que aparece em um comando composto?

  • Importa se o redirecionamento é gerado ou inserido?

  • se eu colocar o redirecionamento no final do comando composto, como posso saber em qual comando do componente o redirecionamento se aplica?

Obrigado.

    
por Tim 21.07.2017 / 06:35

2 respostas

1

Você pode colocar redirecionamentos em qualquer posição em um comando simples (ou seja, invocar um apelido, função, embutido ou executável com parâmetros). Por outro lado, se você quiser aplicar um redirecionamento a comandos compostos, os redirecionamentos devem vir depois. É assim que a sintaxe do shell é projetada. Por exemplo, os seguintes são equivalentes:

<myinput mycommand argument
mycommand <myinput argument
mycommand argument <myinput

Considerando que o redirecionamento não pode ser movido em

while …; do …; done <myinput
{ command1; command2; } <myinput

Você só pode aplicar um redirecionamento a um comando composto se ele terminar com uma palavra-chave ou com pontuação. Para aplicar o redirecionamento a algo como foo && bar ou foo; bar ou foo | bar , coloque o comando entre chaves, por exemplo,

{ foo && bar; } <myinput

Os scripts

while read a; do
  echo "$a"
done <myfile

e

while read a <myfile; do
  echo "$a"
done

são ambos sintaticamente corretos, mas o segundo não faz nada útil. Um operador de redirecionamento em um comando significa:

  1. Abra o arquivo especificado.
  2. Anexe o arquivo especificado ao descritor de arquivo de requisitos (por exemplo, 0 para < ).
  3. Execute o comando.
  4. Feche o descritor de arquivos.

Portanto, read a <myfile abre o arquivo novamente em cada iteração, o que significa que ele continua lendo a primeira linha para sempre.

Se você quiser usar um loop de leitura de tempo e quiser manter a entrada padrão circundante para o corpo do loop, leia um descritor de arquivo diferente.

while read a <&3; do
  # commands that can use stdin
done 3<myfile

O operador de redirecionamento <&3 simplesmente faz a duplicação do descritor de arquivo, ele não “abre o arquivo novamente” - na enumeração acima, não há etapa 1.

    
por 22.07.2017 / 01:53
1

Para comandos simples, o posicionamento de redirecionamento é flexível, desde que esteja na mesma linha e antes de qualquer ; . Todos são válidos:

command1 arg <file
<file command1 arg
command1 <file arg

Você verá que o primeiro formulário é geralmente preferido, estilisticamente falando.

Para comandos conectados por pipe ou condição, o redirecionamento deve estar claramente no mesmo lado do comando associado. Se o primeiro comando precisar receber a entrada, você deseja:

command1 <file || command2

Para o comando2 receber a entrada:

command1 || command2 <file

No caso de while , for e outros compostos compostos por blocos, a necessidade de colocar o redirecionamento no final é apenas uma realidade sintática.

<file { command1 || command2; } # error
{ command1 || command2; } <file  # okay

Um comando composto atua como um único comando neste contexto e, portanto, a entrada redirecionada não pode direcionar o comando2 e excluir o comando1, por exemplo.

É claro que os pipes também são uma opção, então o segundo exemplo acima é semelhante a:

cat file | { command1 || command2; }

E no caso do seu loop while:

cat myfile | while read a; do ...

Eu usei entrada em todos esses exemplos, mas o mesmo se aplica à saída. Onde você precisa prestar atenção é se você usa tanto a entrada quanto a saída ou outras configurações múltiplas de redirecionamento. Os redirecionamentos são processados da esquerda para a direita.

Aqui estão mais algumas leituras:

link

link

    
por 21.07.2017 / 11:37

Tags