Exécuter un processus en arrière-plan dans bash est assez facile.
$ echo "Hello I'm a background task" &
[1] 2076
Hello I'm a background task
[1]+ Done echo "Hello I'm a background task"
Cependant, la sortie est détaillée. Sur la première ligne est imprimé l'ID du travail et l'ID du processus de la tâche d'arrière-plan, puis nous avons la sortie de la commande, enfin nous avons l'ID du travail, son statut et la commande qui a déclenché le travail.
Existe-t-il un moyen de supprimer la sortie de l'exécution d'une tâche en arrière-plan de telle sorte que la sortie ressemble exactement à ce qu'elle serait sans l'esperluette à la fin? C'est à dire:
$ echo "Hello I'm a background task" &
Hello I'm a background task
La raison pour laquelle je demande est que je veux exécuter un processus d'arrière-plan dans le cadre d'une commande de tabulation afin que la sortie de cette commande soit ininterrompue pour avoir un sens.
Pas lié à l'achèvement, mais vous pouvez supprimer cette sortie en plaçant l'appel dans un sous-shell:
(echo "Hello I'm a background task" &)
Dans certaines versions plus récentes de bash et dans ksh93, vous pouvez l'entourer d'un sous-shell ou d'un groupe de processus (c'est-à-dire { ... }
).
/home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null
Hello I'm a background task
/home/shellter $
À partir de la réponse de @ shellter, cela a fonctionné pour moi:
tyler@Tyler-Linux:~$ { echo "Hello I'm a background task" & disown; } 2>/dev/null; sleep .1;
Hello I'm a background task
tyler@Tyler-Linux:~$
Je ne connais pas le raisonnement derrière cela, mais je me suis souvenu d'un ancien post qui reniait empêcher bash de sortir les identifiants de processus.
En s'appuyant sur la réponse ci-dessus, si vous devez autoriser stderr à passer à partir de la commande:
f() { echo "Hello I'm a background task" >&2; }
{ f 2>&3 &} 3>&2 2>/dev/null
Sur la base de cette réponse , je suis venu avec le plus concis et correct:
silent_background() {
{ 2>&3 "$@"& } 3>&2 2>/dev/null
disown &>/dev/null # Prevent whine if job has already completed
}
silent_background date
Désolé pour la réponse à un ancien post, mais je pense que cela est utile aux autres, et c'est la première réponse sur Google.
J'avais un problème avec cette méthode (sous-coquilles) et j'utilisais 'wait'. Cependant, comme je l'exécutais dans une fonction, j'ai pu le faire:
function a {
echo "I'm background task $1"
sleep 5
}
function b {
for i in {1..10}; do
a $i &
done
wait
} 2>/dev/null
Et quand je le lance:
$ b
I'm background task 1
I'm background task 3
I'm background task 2
I'm background task 4
I'm background task 6
I'm background task 7
I'm background task 5
I'm background task 9
I'm background task 8
I'm background task 10
Et il y a un délai de 5 secondes avant de récupérer mon invite.
Essayer:
user@Host:~$ read < <( echo "Hello I'm a background task" & echo $! )
user@Host:~$ echo $REPLY
28677
Et vous avez caché à la fois le sortie et le PID . Notez que vous pouvez toujours récupérer le PID à partir de $ REPLY
La solution de sous-shell fonctionne, mais je voulais également pouvoir attendre les travaux en arrière-plan (et ne pas avoir le message "Terminé" à la fin). $!
à partir d'un sous-shell n'est pas "en attente" dans le shell interactif actuel. La seule solution qui a fonctionné pour moi a été d'utiliser ma propre fonction d'attente, qui est très simple:
myWait() {
while true; do
sleep 1; STOP=1
for p in $*; do
ps -p $p >/dev/null && STOP=0 && break
done
((STOP==1)) && return 0
done
}
i=0
((i++)); p[$i]=$(do_whatever1 & echo $!)
((i++)); p[$i]=$(do_whatever2 & echo $!)
..
myWait ${p[*]}
Assez facile.