echo
sempre é enviado para o stdout 1 . echo foo
sempre faz um write(1, "foo\n")
.
Quando você executa echo foo > file
, o shell altera o stdout do comando echo
para um novo arquivo file
. echo foo
, então, ainda faz um write(1, "foo\n")
, mas desta vez seu stdout (seu descritor de arquivo 1) aponta para file
, não para o stdout que ele herda do shell.
Se você quiser escrever para o stdout sem que o stdout seja redirecionado , apenas escreva:
echo foo
Se você quiser que o recurso apontado por stdout seja reaberto (e truncado) antes de cada echo
, então é mais complicado.
No Linux (e no Linux apenas), você pode fazer:
echo foo > /dev/fd/1
echo bar > /dev/fd/1
# now the file stdout points to (if it's a regular file) contains "bar"
No Linux, /dev/fd/1
é um link simbólico para o arquivo que está aberto no stdout. Então, abri-lo novamente com >
irá truncá-lo (em outros Unices, > /dev/fd/n
é como dup2(n,1)
para não truncar o arquivo). Isso não funcionará se o stdout for para um soquete.
Caso contrário, você pode chamar ftruncate()
no stdout (fd 1) para truncá-lo:
perl -e 'truncate STDOUT,0'
echo foo
perl -e 'truncate STDOUT,0'
echo bar
Se, em vez disso, você quiser essas palavras, quando o stdout é um terminal para substituir um ao outro na tela, você pode usar caracteres de controle do terminal para afetar o posicionamento do cursor.
printf %s FOO
printf '\r%s' BAR
fará com que BAR sobrescreva FOO porque \r
é os caracteres de controle que instrui o terminal a mover o cursor para o início da linha.
Se você fizer isso:
printf %s FOOBAR
printf '\r%s' BAZ
no entanto, você verá BAZBAR
na tela. Você pode querer usar outra seqüência de controle para limpar a linha. Enquanto \r
significa que o retorno do carro é universal, a sequência de controle para limpar a tela varia de um terminal para o próximo. O melhor é consultar o banco de dados terminfo com tput
para descobrir:
clr_eol=$(tput el)
printf %s FOOBAR
printf '\r%s%s' "$clr_eol" BAZ
1 se estiver usando o shell Korn ou Z, outro comando de saída que suporta gravação em outros descritores de arquivo é print
: print -u2 FOO
, por exemplo, escreve FOO
to print
é stderr. Com echo
e em shells semelhantes a Bourne, você pode fazer echo >&2 FOO
para obter o mesmo resultado. echo
ainda está gravando em seu stdout, mas seu stdout foi duplicado no stderr do shell usando o operador de redirecionamento >&2