Você está redirecionando a entrada de tee
, não bash
. Use:
bash << EOF | tee foo
echo Hello
EOF
Mais alguns exemplos para ilustrar como funciona:
bash << EO1 3<< EO | tee 3<< EO3 foo 4<< EO4
fed (as a deleted temp file open in read-only mode) to bash fd 0
EO1
fed to bash fd 3 without $variable and $(cmd) expansion
EO2
fed to tee fd 3
(not that tee does anything with its fd 3)
EO3
fed to tee fd 4
(see how, like any redirection operator 3<< END can appear anywhere on
the command line (for simple commands at least))
EO4
Redirecionando comandos compostos:
{ head -n2; wc -l; } << EOF
fed as fd 0 for the whole command group
$(ps -e)
EOF
Ou:
if head -n1; then
head -n2
fi << EOF
1
2
3
EOF
Você pode reutilizar o mesmo token de finalização:
$ ls -l /proc/self/fd << E 3<< E >&2 | 3<< E 4<< E ls -l /proc/self/fd
pipe heredoc> E
pipe heredoc> E
pipe heredoc> E
pipe heredoc> E
total 0
lr-x------ 1 stephane stephane 64 Feb 24 12:50 0 -> /tmp/zshLiVzp3 (deleted)
lrwx------ 1 stephane stephane 64 Feb 24 12:50 1 -> /dev/pts/5
lrwx------ 1 stephane stephane 64 Feb 24 12:50 2 -> /dev/pts/5
lr-x------ 1 stephane stephane 64 Feb 24 12:50 3 -> /tmp/zshFLbQ7T (deleted)
lr-x------ 1 stephane stephane 64 Feb 24 12:50 4 -> /proc/25749/fd/
total 0
lr-x------ 1 stephane stephane 64 Feb 24 12:50 0 -> pipe:[70735808]
lrwx------ 1 stephane stephane 64 Feb 24 12:50 1 -> /dev/pts/5
lrwx------ 1 stephane stephane 64 Feb 24 12:50 2 -> /dev/pts/5
lr-x------ 1 stephane stephane 64 Feb 24 12:50 3 -> /tmp/zshL3KBp3 (deleted)
lr-x------ 1 stephane stephane 64 Feb 24 12:50 4 -> /tmp/zshcJjS7T (deleted)
lr-x------ 1 stephane stephane 64 Feb 24 12:50 5 -> /proc/25748/fd/
Por que o primeiro comando history
é executado nesse novo bash
in:
$ bash | tee foo <<EOF
echo Hello
EOF
$ history
$ history
1 ...
Isso porque bash
stdin ainda é o terminal, mas seu stdout é um canal morto (na outra extremidade do canal, tee
redirecionou seu stdin desse arquivo temporário de exclusão, portanto, o final de leitura desse tubo está fechado).
bash
não escreve seu prompt ou o eco do que você digita em seu stdout (o canal morto), mas no terminal, de modo que bash
permitirá que você digite history
no primeiro prompt.
No entanto, esse history
(que é um embutido, assim executado pelo processo bash
, não um filho), gravará sua saída para esse canal morto. Ao fazer isso, o processo bash
receberá um sinal SIGPIPE (já que não há leitor) e morrerá.
O próximo prompt será emitido pelo shell de chamada.