Ao experimentar o redirecionamento de saída e a substituição de processos, deparei-me com o seguinte comando e sua saída resultante:
me @ elem: ~ $ echo foo>> (gato); barra de eco Barra me @ elem: ~ $ foo
(Sim, essa nova linha vazia no final é intencional.)
Então a barra do eco do bash, imprime meu prompt habitual, o eco do eco, o eco é uma nova linha e deixa meu cursor lá. Se eu pressionar enter novamente, ele imprimirá meu prompt em uma nova linha e deixará o cursor seguindo (como esperado quando alguém pressiona enter em uma linha de comando vazia).
Eu esperava que ele escrevesse foo em um descritor de arquivo, cat o lê e echo foo, a segunda barra de eco de eco e, em seguida, volta ao prompt de comando. Mas esse claramente não é o caso.
Alguém poderia explicar o que está acontecendo?
bash
shell
process-substitution
concurrency
Stanley Yu
fonte
fonte
Respostas:
Você pode ver
foo
exibido antesbar
, depoisbar
ou mesmo após o prompt, dependendo do tempo. Adicione um pequeno atraso para obter um tempo consistente:bar
aparece imediatamente,foo
depois de um segundo e o próximo prompt após outro segundo.O que está acontecendo é que o bash executa substituições de processos em segundo plano.
sleep 1; cat
e configura um pipe para ele.echo foo
. Como isso não preenche o buffer do canal, oecho
comando termina sem bloquear.echo bar
.sleep 2
.sleep 1
.sleep 1
retorna no subprocesso. O subprocesso continua executandocat
.cat
copia sua entrada para sua saída (que é exibida na tela) e retorna.sleep 2
retorna. O processo principal do shell termina a execução e você vê o próximo prompt.fonte
Você não precisa de substituição de processo para obter esse efeito. Tente o seguinte:
Você obterá o mesmo resultado (sem o
bar
; deixarei isso como um exercício) e pelo mesmo motivo. Nos dois casos,cat
é iniciado como uma tarefa em segundo plano. Na minha linha aqui, isso é explícito. No caso de substituição de processo, também é explícito - é um processo separado anexado a um descritor de arquivo de nome - mas talvez não seja tão óbvio.O processo filho não termina necessariamente antes de
bash
imprimir o próximo prompt. E, como sua saída é armazenada em buffer, ela não produz nada até terminar. Nesse ponto, o bash acabou de ser impresso$
no stderr e agora o processo em segundo plano sai após a impressãofoo
e uma nova linha.fonte