l'exécution de la boucle bash pendant l'exécution de la commande
Je veux créer un script bash qui exécute une commande et en attendant effectue d'autres choses, avec la possibilité de tuer la commande si le script est tué. Dire, exécute un cp d'un fichier de grande taille et dans le même temps imprime le temps écoulé depuis la copie commencé, mais si le script est tué, il tue aussi la copie.
Je ne pas souhaitez utiliser rsync, pour 2 raisons: 1) est lente et 2) je veux apprendre comment le faire, il pourrait être utile.
J'ai essayé ceci:
until cp SOURCE DEST
do
#evaluates time, stuff, commands, file dimensions, not important now
#and echoes something
done
mais il ne veut pas exécuter l' do - done
bloc, tel qu'il est en attente que la copie se termine. Pourriez-vous s'il vous plaît suggérer quelque chose?
source d'informationauteur marco
Vous devez vous connecter pour publier un commentaire.
until
est à l'opposé dewhile
. Il n'a rien à voir avec faire des trucs alors qu'une autre commande s'exécute. Pour cela vous avez besoin pour exécuter votre tâche en arrière-plan avec&
.kill -0
vérifie si un processus est en cours d'exécution. Notez qu'il ne fait pas de signal le processus et de le tuer, comme le nom pourrait le faire croire. Pas avec un signal de 0, au moins.Il y a trois étapes dans la résolution de votre problème:
Exécuter une commande en arrière-plan, donc, il va continuer à courir pendant que votre script ne fait autre chose. Vous pouvez le faire en suivant la commande avec
&
. Voir la la section sur le Contrôle du Travail dans le Bash Manuel de Référence pour plus de détails.Garder une trace de la commande de l'état, de sorte que vous saurez si elle est toujours en cours d'exécution. Vous pouvez le faire avec la variable spéciale
$!
qui est le PID (identificateur de processus) de la dernière commande exécutée en arrière-plan, ou vide si pas de fond de commande a été commencé. Linux crée un répertoire/proc/$PID
pour chaque processus en cours d'exécution et le supprime lorsque le processus s'arrête, de sorte que vous pouvez vérifier l'existence de ce répertoire pour savoir si le fond de commande est toujours en cours d'exécution. Vous pouvez en apprendre plus que vous avez toujours voulu savoir sur/proc
du Projet de Documentation Linux est Hiérarchie du Système de fichier de la page ou Advanced Bash Scripting Guide.Tuer le fond de commande si votre script est tué. Vous pouvez faire cela avec le
trap
de commande, qui est un bash builtin commande.Rassembler les morceaux:
Noter que nous avons vérifier la
/proc
répertoire pour savoir si le fond de commande est toujours en cours, carkill -0
va générer une erreur si elle a été appelée lorsque le processus n'existe plus.Mise à jour pour expliquer l'utilisation de
trap
:La syntaxe est
trap [arg] [sigspec …]
oùsigspec …
est une liste de signaux de attraper, etarg
est une commande à exécuter lorsque l'un quelconque de ces signaux est soulevée. Dans ce cas, la commande est une liste:C'est une commune bash idiome qui tire parti de la façon
||
est traitée. Une expression de la formecmd1 || cmd2
permettra d'évaluer autant de succès sicmd1
OUcmd2
réussit. Mais bash est intelligent: sicmd1
réussit, bash sait que l'expression complète doit également réussir, de sorte qu'il n'a pas pris la peine d'évaluercmd2
. D'autre part, sicmd1
échoue, le résultat decmd2
détermine le résultat global de l'expression. Donc une caractéristique importante de||
est que il va exécutercmd2
seulement sicmd1
échoue. Cela signifie que c'est un raccourci pour l' (invalides) séquence:Avec cela à l'esprit, nous pouvons voir que
permettra de tester si
$!
est vide (ce qui signifie que la tâche en arrière-plan n'a jamais été exécutée). Si cela échoue, ce qui signifie que la tâche était exécuté, il tue à la tâche.Ce que vous voulez est de faire deux choses à la fois dans le shell. La manière habituelle de le faire est avec un travail. Vous pouvez démarrer une tâche en arrière-plan pour la fin de la commande avec une esperluette.
Vous pouvez ensuite utiliser la
jobs
de commande pour vérifier son état.Lire la suite:
ici est la façon la plus simple de le faire à l'aide de
ps -p
:Cela permettra d'exécuter toutes les
10 seconds
lacommand_2
si lecommand_1
est toujours en cours d'exécution en arrière-plan .espérons que cela vous aidera 🙂