Suponha que eu tenha o seguinte canal:
a | b | c | d
Como posso esperar pela conclusão de c
(ou b
) em sh
ou bash
? Isso significa que o script d
pode iniciar a qualquer momento (e não precisa ser esperado), mas requer saída completa c
para funcionar corretamente.
O caso de uso é um difftool
para git
comparar imagens. É chamado git
e precisa processar sua entrada (a a | b | c
parte) e exibir os resultados da comparação (a d
parte). O chamador excluirá a entrada necessária para a
e b
. Isso significa que, antes de retornar do script, o processo c
(ou b
) deve terminar. Por outro lado, não posso esperar d
porque isso significa que estou aguardando a entrada do usuário.
Eu sei que posso gravar os resultados de c
em um arquivo temporário ou talvez usar um FIFO no bash
. (Não tenho certeza se o FIFO ajudará.) É possível conseguir isso sem a necessidade de arquivos temporários sh
?
EDITAR
Talvez fosse suficiente se eu pudesse descobrir o ID do processo c
(ou b
) de uma maneira confiável. Em seguida, todo o canal poderia ser iniciado de forma assíncrona e eu poderia esperar por um ID do processo. Algo ao longo das linhas de
wait $(a | b | { c & [print PID of c] ; } | d)
EDIT ^ 2
Encontrei uma solução, comentários (ou ainda melhores soluções) são bem-vindos.
d
iniciarc
a saída do processamento somente após ac
conclusão? Você não desejad
iniciar o processamento de cada linha de saída como ela vem?d
é livre para começar quando quiser, masc
precisa terminar antes que eu possa seguir em frente.d
pode começar quando quiser, o que exatamente você está esperando?d
não usar a saída de,c
então parece não fazer sentido fazerd
parte do pipeline. Mas sed
usar a entrada,d
deve trabalhar um pouco na entrada depois de ler tudo para que sua abordagem faça alguma diferença.Respostas:
A notificação pode ser feita, por exemplo, por um sinal para um PID que foi passado em uma variável de ambiente (
kill -USR1 $EXTPID
) ou criando um arquivo (touch /path/to/file
).Outra ideia:
Você executa o próximo processo (aquele em que você pode iniciar o processo):
ou
fonte
notify
poderia ser executado antes de eu configurar a armadilha de sinal. Como posso ter certeza de não perder esse sinal?trap
definição.{ c; bg; }
ou{ c; exit 0; }
parece não funcionar.Se eu entendi sua pergunta corretamente, isso deve funcionar:
(o truque do fd 3 é porque alguns shells (a maioria) redirecionam stdin para / dev / null com
&
).fonte
No bash, você pode usar uma substituição de processo . O comando na substituição do processo é executado de forma assíncrona, não é esperado.
fonte
bash
apenas, certo - semsh
suporte?Isto é o que eu descobri por tentativa e erro, com a ajuda da contribuição de Hauke:
Equivalentemente:
(O último é mais explícito, porque
{}
será executado em um subshell de qualquer maneira, se estiver dentro de um pipe.)Alguns outros sinais (incluindo
QUIT
,TERM
eUSR1
) de trabalho, também, no entanto, neste caso, a descrição de que o sinal é mostrado no terminal.Gostaria de saber se esta é a intenção original do
PIPE
sinal. De acordo com o manual :Isso significa que, quando eu envio artificialmente um sinal de pipe para o subshell, ele termina silenciosamente, deixando o consumidor final (
d
) sozinho.Isso funciona em ambos
sh
ebash
.fonte
Você pode usar o
sponge
programa no pacote "moreutils":a | b | c | sponge | d
a esponja irá para o final da
c
produção antes de ser canalizadad
. Espero que seja o que você queria.fonte
Você pode apenas fazer:
Assim, quando
d
terminar,cat
ele absorverá o restante dac
produção até que termine.Está bem. Após os comentários, acho que a resposta é começar diretamente
d
em segundo plano.Faz:
ou use a solução de Stephane Chazelas se houver problemas com a
d
leitura do stdin .fonte
c
termina antesd
e tenho que esperar atéc
terminar, mas não me importod
.c
terminar ed
ainda estiver em execução? Matard
?d
possui uma GUI e pode executar até que o usuário a feche.a
,b
ec
terminam o trabalho, eles fecham o stdout e saem; e sód
continua sendo executado. Deseja enviard
para o plano de fundo quandoc
terminar? É isso?d
deve ser enviado para o plano de fundo assim quec
terminar.