echo “olá” & 0 | arquivo.txt não grava no arquivo.txt

5

Estou aprendendo sobre os comandos básicos do terminal.

Por que este comando não está funcionando como eu esperava?

echo "hello" >&0 | > file.txt

Eu sei que posso simplesmente digitar echo "hello" > file.txt mas estou aprendendo sobre o uso de canos. Eu só quero mostrar a palavra "olá" para um arquivo.

    
por Prof-Wiz 28.03.2018 / 13:41

4 respostas

15

No bash, um comando vazio com um redirecionamento apenas abre o arquivo da maneira associada ao redirecionamento e, em seguida, o fecha *. echo "hello" >&0 | > file.txt é um comando composto composto por dois comandos simples echo "hello" >&0 , > file.txt , piped. O segundo comando está vazio, então o bash apenas abre o arquivo para escrita, truncando-o e depois fecha-o.

Em um terminal, geralmente a entrada, saída e erro padrão são todos conectados ao terminal. Então, quando você redireciona stdout para stdin, ele ainda está apontando para o terminal, e a saída de echo hello >&0 é vista no terminal e não é enviada para o pipe.

Em zsh, um comando vazio com um redirecionamento ter cat seja o comando. Portanto, echo "hello" >&0 | > file.txt é efetivamente echo "hello" >&0 | cat > file.txt e você verá o efeito desejado. Isso não é possível no bash. Aqui, você verá outro recurso de redirecionamento não visto no bash: quando você redireciona a saída de um comando várias vezes, a saída é enviada para cada um desses destinos redirecionados (assim, o hello é enviado para o terminal e para o tubo). No bash, é enviado apenas para o último local redirecionado.

* A exceção é a substituição de comandos com stdin redirecionado. Em $(<some-file) , o bash lerá o conteúdo de some-file e o usará como o valor da substituição do comando.

    
por muru 28.03.2018 / 14:35
12

Ah, eu vejo o que você estava pensando (eu acho). Você tentou

echo hello | > file

e nada aconteceu com file , então você pensou, talvez eu precise transformar a saída do meu comando em stdin, redirecionando:

echo hello >&0 

Mas transformar stdout em stdin é exatamente o que um pipe faz. Leva stdout e passa para o comando à sua direita como stdin. Se você redirecionar o stdout, nada passará pelo canal:

$ echo hello >&0 | cat > file
hello
$ cat file
$

(nada lá)

Mas hello apareceu no terminal, que está lendo stdin como de costume:

$ cat /dev/fd/0
hi
hi
I am talking to myself!
I am talking to myself!

e assim por diante ...

Se não redirecionarmos ...

$ echo hello | cat > file
$ cat file
hello

O stdout de echo hello passou pelo canal (em vez de para o terminal) e tornou-se stdin de cat .

Então, o pipe faz o que você queria fazer (transformar stdout em stdin e conectá-lo ao comando correto) e você não precisa fazer isso sozinho, mexendo nos descritores de arquivos.

Por que um comando vazio com redirecionamento não faz o que você quer, veja a resposta de muru .

    
por Zanna 28.03.2018 / 15:24
5

Eu acho que você quer escrever a saída para o arquivo e stdout também.

echo hello > file.txt 

faz isso parcialmente, mas pula a saída padrão (não imprime nada para o console). Se você quiser também, use o comando tee como abaixo:

echo hello | tee file.txt

Ele canaliza a saída de echo para a entrada de tee e, em seguida, o tee grava na tela e no arquivo.txt também.

Se você quiser apenas imprimir no arquivo use o comando cat como abaixo:

echo hello | cat >file.txt

Além disso, verifique esta resposta para saber como os redirecionamentos funcionam: link

e isso é como o pipe funciona: link

Dê uma olhada na página do manual do comando tee também.

    
por Levente M 28.03.2018 / 14:00
0
  • O símbolo > é para o redirecionamento de arquivos para o início de um arquivo.
  • O símbolo >> é para o redirecionamento de arquivos para o final de um arquivo (anexar).
  • O símbolo | é para "canalizar" ou passar a saída de um comando como entrada para outro comando.

    $ echo "Hello" > file.txt
    $ echo "World!" >> file.txt
    $ cat file.txt
    Hello
    World!
    $ cat file.txt | grep !
    World!
    

O comando grep (impressão de expressão regular global) procura em um arquivo por uma determinada seqüência de pesquisa e imprime a linha em que está.

O &>0 de acordo com o Guia de scripts do Bash avançado :

&>filename
  # Redirect both stdout and stderr to file "filename."
  # This operator is now functional, as of Bash 4, final release.

No seu caso, o nome do arquivo era 0, que é a entrada padrão. Por isso, está redirecionando toda a saída para entrada. O melhor que posso dizer é uma referência circular que não funciona. A sintaxe usada é >&0 , que redireciona a saída para entrada. Que também parece ser uma referência circular.

Os "nomes dos arquivos" são:

  • 0 entrada padrão
  • 1 saída padrão
  • 2 saída de erro padrão

A maneira tradicional de usar o descritor de arquivo 0 (entrada padrão) por meio do redirecionamento de arquivos é:

 0< FILENAME
    < FILENAME
      # Accept input from a file.
      # Companion command to ">", and often used in combination with it.
      #
      # grep search-word <filename

Se você quiser usar o comando echo e | juntos (como a resposta de Zanna aponta), você pode usar:

$ echo "hello" | cat > file.txt
$ cat file.txt
hello
    
por WinEunuuchs2Unix 29.03.2018 / 02:23