Supposons que j'ai le tuyau suivant:
a | b | c | d
Comment puis-je attendre la fin de c
(ou b
) dans sh
ou bash
? Cela signifie que le script d
peut démarrer à tout moment (et n'a pas besoin d'être attendu) mais nécessite une sortie complète de c
pour fonctionner correctement.
Le cas d'utilisation est un difftool
pour git
qui compare les images. Il est appelé par git
et doit traiter son entrée (la a | b | c
partie) et afficher les résultats de la comparaison (la d
partie). L'appelant supprimera l'entrée requise pour a
et b
. Cela signifie qu'avant de revenir du script, le processus c
(ou b
) doit se terminer. D'un autre côté, je ne peux pas attendre d
car cela signifie que j'attends la saisie de l'utilisateur.
Je sais que je peux écrire les résultats de c
dans un fichier temporaire, ou peut-être utiliser un FIFO dans bash
. (Je ne sais pas si le FIFO va aider, cependant.) Est-il possible d'y parvenir sans fichiers temporaires sh
?
ÉDITER
Il serait peut-être suffisant que je puisse trouver l'ID de processus du c
(ou b
) processus de manière fiable. Ensuite, le tube entier pourrait être démarré de manière asynchrone et je pouvais attendre un ID de processus. Quelque chose dans le sens de
wait $(a | b | { c & [print PID of c] ; } | d)
MODIFIER ^ 2
J'ai trouvé une solution, les commentaires (ou encore meilleures solutions) sont les bienvenus.
d
commencerc
la sortie du traitement uniquement après lac
fin? Vous ne voulezd
pas commencer à traiter chaque ligne de sortie au fur et à mesure?d
est libre de commencer quand bon lui semble, maisc
doit se terminer avant que je puisse continuer.d
pouvez commencer quand vous le souhaitez, qu'attendez-vous exactement?d
n'utilise pas la sortie dec
alors il ne semble pas logique de faired
partie du pipeline. Mais sid
utilise l'entrée, ild
faut travailler un moment sur son entrée après l'avoir lue pour que votre approche fasse la différence.Réponses:
La notification peut être effectuée par exemple par un signal à un PID qui a été passé dans une variable d'environnement (
kill -USR1 $EXTPID
) ou en créant un fichier (touch /path/to/file
).Une autre idée:
Vous exécutez le processus suivant (celui que vous souhaitez démarrer) à partir du pipeline:
ou
la source
notify
pourrait être exécuté avant de configurer le piège de signal. Comment puis-je m'assurer de ne pas manquer ce signal?trap
a été défini.{ c; bg; }
ou{ c; exit 0; }
ne semble pas fonctionner.Si je comprends bien votre question, cela devrait fonctionner:
(l'astuce fd 3 est parce que certains (la plupart) des shells redirigent stdin vers / dev / null avec
&
).la source
En bash, vous pouvez utiliser une substitution de processus . La commande dans la substitution de processus s'exécute de manière asynchrone, elle n'est pas attendue.
la source
bash
seulement, non - pas desh
support?C'est ce que j'ai trouvé par essais et erreurs, avec l'aide de la contribution de Hauke:
De manière équivalente:
(Ce dernier est plus explicite, car
{}
s'exécutera de toute façon dans un sous-shell si à l'intérieur d'un tuyau.)D'autres signaux (y compris
QUIT
,TERM
etUSR1
) le travail aussi, mais dans ce cas , la description du signal est affiché sur le terminal.Je me demande si c'est l'intention originale du
PIPE
signal. Selon le manuel :Cela signifie que lorsque j'envoie artificiellement un signal de tuyau au sous-shell, il se termine silencieusement, laissant le consommateur final (
d
) seul.Cela fonctionne à la fois dans
sh
etbash
.la source
Vous pouvez utiliser le
sponge
programme du package "moreutils":a | b | c | sponge | d
l'éponge sera pour la fin de
c
la sortie avant de la canaliserd
. J'espère que c'est ce que tu voulais.la source
Vous pouvez simplement faire:
Ainsi, une fois
d
terminé, lecat
absorbera le reste dec
la production jusqu'à ce qu'il se termine.D'accord. Après les commentaires, je pense que la réponse est de commencer directement
d
en arrière-plan.Faire:
ou utilisez la solution de Stéphane Chazelas en cas de problème de
d
lecture depuis stdin .la source
c
termine plus tôt qued
, et je dois attendre jusqu'à lac
fin, mais je m'en fiched
.c
terminé etd
en cours d'exécution? Tuerd
?d
possède une interface graphique et peut s'exécuter jusqu'à ce que l'utilisateur la ferme.a
,b
etc
finissant leur travail, ils ferment la sortie standard et sortent; et ned
reste en cours d'exécution. Voulez-vous envoyerd
à l'arrière-plan une foisc
terminé? Est-ce que c'est ça?d
doit être envoyé à l'arrière-plan une foisc
terminé.