J'ai un script bash qui ressemble à ceci:
##script
#!/bin/bash
rm data*
rm logfile*
for i in {1..30}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
done
Je voudrais créer une autre boucle for après la première pour continuer pendant 30. Par exemple
##script
#!/bin/bash
rm data*
rm logfile*
for i in {1..30}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
for i in {31..60}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
done
Je voudrais que le premier ensemble de travaux se termine avant de commencer le nouvel ensemble. Mais à cause de nohup
cela, il semble qu'ils soient tous exécutés simultanément.
Je l'ai nohup
parce que je me connecte à distance à mon serveur et que je démarre les travaux là-bas, puis ferme mon bash. Existe-t-il une solution alternative?
wait
builtin.Réponses:
Vous voudrez utiliser la
wait
commande pour le faire pour vous. Vous pouvez soit capturer tous les ID de processus enfants et les attendre spécifiquement, ou s'ils sont les seuls processus d'arrière-plan que votre script crée, vous pouvez simplement appelerwait
sans argument. Par exemple:la source
Quelques points:
Si votre objectif
nohup
est d'empêcher une sortie de shell distante de tuer vos processus de travail, vous devez l'utilisernohup
sur le script lui-même, et non sur les processus de travail individuels qu'il crée.Comme expliqué ici ,
nohup
empêche uniquement les processus de recevoir SIGHUP et d'interagir avec le terminal, mais il ne rompt pas la relation entre le shell et ses processus enfants.En raison du point ci-dessus, avec ou sans
nohup
, un simplewait
entre les deuxfor
boucles provoquera l'for
exécution de la seconde uniquement après la fin de tous les processus enfants démarrés par la premièrefor
.Avec un simple
wait
:Si vous devez exécuter le second
for
uniquement s'il n'y a pas eu d'erreurs dans le premier, vous devrez enregistrer chaque PID de travailleur avec$!
et les transmettre àwait
:la source
R
oucc1plus
dans latop
commandewait
faitbash
attendre les travaux d'arrière-plan qu'il a engendré lui-même, rien d'autre. Il peut y avoir une certaine confusion ici - cesfor
boucles, les avez-vous enregistrées dans un fichier et les avez-vous appelées en tant que script (ce que je supposais, à cause de la##script
ligne), ou les saisissez-vous à la main dans le terminal?Utilisez la fonction
fg
intégrée. Il attend la fin des processus d'arrière-plan.Essayez
help fg
pour plus de détails.la source
Si vous insérez quelque chose comme le segment de code suivant entre vos deux
for
boucles, cela pourrait aider.Bien sûr, si votre application
Rscript
a une chance de ne pas aboutir et de s'attarder, votre deuxième boucle for peut ne pas avoir de chance de s'exécuter. Le segment de code ci-dessus suppose que tous les processus avec l'identifiantRscript --vanilla
se termineront et disparaîtront correctement. Sans savoir ce que fait votre application et comment elle fonctionne, je dois me fier à cette hypothèse.ÉDITER
À la lumière des commentaires, cela conviendrait mieux à vos besoins. (il comprend votre code d'origine ainsi que la logique de vérification de l'achèvement)
la source
top
s'afficheR
parfois oucc1plus
.ps -ef
liste. Ou après chaquenohup
commande, enregistrez le PID dans une variable (de préférence un tableau) parecho ${!}
et vérifiez ce groupe de PID. Quand ils disparaissent tous, vous pouvez passer à la deuxièmefor
boucle