Faire écho à la progression d'un processus d'arrière-plan sans invite de détournement

10

Considérez le script simple hello:

#!/bin/bash

echo 'hello world!'

Maintenant, depuis bash, si j'essaie de l'exécuter en arrière-plan:

$ hello &
[1] 12345
$ hello world!
 <--- prompt is stuck here until I hit enter!
[1]+ Done
$  <--- prompt back to normal

Ce que je préfère voir:

$ hello &
[1] 12345
[1]+ hello world!
[1]+ Done
$  <--- prompt normal the whole time

Comment puis-je changer le comportement?

Dave Johnson
la source

Réponses:

13

C'est une question de timing: bash lance la hellocommande en arrière-plan, puis il affiche une invite pour vous permettre d'entrer une nouvelle commande, puis la commande d'arrière-plan imprime une sortie. Lorsque vous entrez la ligne de commande suivante (une ligne de commande vide, si vous appuyez simplement sur Enter), bash affiche la notification que le travail d'arrière-plan est terminé, puis l'invite suivante.

Vous pouvez essayer un script qui commence par sleep 3et commencer à taper juste après avoir lancé le script en arrière-plan, pour voir ce qui se passe à un rythme que vous pouvez suivre.

Vous pouvez demander à bash de vous informer immédiatement de la fin d'un travail en arrière-plan en définissant l' notifyoption avec set -b. Ensuite, vous verrez:

$ set -b
$ hello &
[1] 12345
$ hello world!
[1]+ Done

Bash ne redessine pas l'invite dans ce cas. Vous modifiez toujours une ligne de commande sur la ligne d'invite qui est apparue avant l'impression du travail d'arrière-plan hello world!. Vous pouvez redessiner la ligne actuelle en appuyant sur Esc 1 Ctrl+ L. Vous voudrez peut-être lier la commande redraw-current-lineà une clé plus pratique; par exemple, pour avoir Ctrl+ Lredessiner la ligne actuelle et Ctrl+ Alt+ Leffacer l'écran, ajoutez les lignes suivantes à votre ~/.inputrc:

"\C-l": redraw-current-line
"\e\C-l": clear-screen

Je ne connais aucun moyen de faire bash redessiner automatiquement la ligne d'invite. Zsh le fait par défaut.

Gilles 'SO- arrête d'être méchant'
la source