Jai un script que je voudrais bifurquer à un moment donné, donc deux copies du même script sont en cours dexécution.
Par exemple , Je voudrais que le script bash suivant existe:
echo $$ do_fork() echo $$
Si ce script bash existait vraiment, le résultat attendu serait:
<ProcessA PID> <ProcessB PID> <ProcessA PID>
ou
<ProcessA PID> <ProcessA PID> <ProcessB PID>
Y a-t-il quelque chose que je peux mettre à la place de « do_fork () » pour obtenir ceci type de sortie, ou pour que le script bash fasse un fork de type C?
Answer
Oui. La fourche est orthographiée &
:
echo child & echo parent
Ce qui peut vous dérouter, cest que $$
nest pas le PID du processus shell, cest le PID du processus shell original . Le but de le faire de cette façon est que $$
est un identifiant unique pour une instance particulière du script shell: il ne change pas pendant lexécution du script, et il est différent de $$
dans tout autre exécution simultanée scénario. Une manière dobtenir le PID réel du processus shell est sh -c "echo $PPID"
.
Le flux de contrôle dans le shell nest pas le même que C. Si en C vous « d write
first(); fork(); second(); third();
alors un équivalent du shell est
after_fork () { second; third; } first; after_fork & after_fork
La forme simple du shell first; child & parent
correspond à lidiome C habituel
first(); if (fork()) parent(); else child();
&
et $$
existe et se comporte de cette façon dans tous les shell de style Bourne et dans (t) csh. $PPID
nexistait pas dans le Bourne orignal shell mais est dans POSIX (donc cest dans ash, bash, ksh, zsh,…).
Commentaires
Réponse
Oui, il « sappelle sous-shell . Le code shell entre parenthèses est exécuté comme un subshell (fork). Cependant, le premier shell attend normalement que lenfant se termine. Vous pouvez le rendre asynchrone en utilisant le terminateur &
. Regardez-le en action avec quelque chose comme ceci:
#!/bin/bash (sleep 2; echo "subsh 1")& echo "topsh"
$ bash subsh.sh
Commentaires
- Les parenthèses créent un sous-shell , mais que ' s fork + wait.
&
est fork seul. Si vous voulez exécuter plusieurs pipelines dans le processus enfant, il ' est suffisant pour utiliser des accolades (qui effectuent un regroupement sans créer de processus enfant):{ sleep 2; echo child; } &
Réponse
Il ny a pas de version native bash (ou, à ma connaissance, tout autre moyen typique du shell * nix) de le faire. Il existe de nombreuses façons de générer des processus forkés qui font autre chose de manière asynchrone, mais je ne pense pas quil y ait quoi que ce soit qui suive la sémantique exacte de lappel système fork ().
Lapproche typique serait être de faire en sorte que votre script de niveau supérieur génère des assistants qui ne font que le travail que vous voulez diviser. Si vous faites $0 $@ &
ou autre chose, vous « recommencerez au début et devrez comprendre cela en quelque sorte.
Je commence en fait à penser à plusieurs façons intelligentes de faire exactement cela ….
Mais , avant que mon cerveau ne soit trop emporté par ça, je pense quune très bonne règle est la suivante: si vous « essayez décrire quelque chose en shell et que ça devient plein de trucs astucieux et vous « souhaitez plus de fonctionnalités de langage, il est temps de passer à un vrai langage de programmation .
Commentaires
- Bien que votre remarque soit bien prise, la syntaxe de bash ' est sans doute difficile et elle ' manque les structures de données et les fonctionnalités plus élégantes de Perl ou Python, bash est aussi réel que possible – dans son domaine . Cest un langage spécifique à un domaine, et je dirais même mieux (plus succinct, plus simple) que par exemple Python dans de nombreux cas. Pouvez-vous administrer une salle pleine de systèmes sans connaître Python? Oui. Pouvez-vous faire cela et ne pas connaître un coup de langue de bash [programmation]? Je ne voudrais ' pas essayer. Après 30 ans de programmation shell, je vous dis que ' est aussi réel que possible. Et oui, je parle Python. Mais ne ' t confondre les jeunes.
- Cela dit, techniquement, jaime plus cette réponse. Dire que " & " est la réponse à lutilisateur ' s question, " fork à un point donc deux copies du même script sont en cours dexécution " est à mon esprit déroutant. Ce que fait " & ", selon le manuel bash, est " … exécute la commande [donnée] en arrière-plan dans un sous-shell. " Il doit terminer une commande, et cela implique un fork (techniquement , sous Linux, un clone ()), mais à ce stade, deux copies du même script ne sont pas en cours dexécution.
&
est fork, il ny a ' aucun exécutable impliqué. Fork + exec est lorsque vous lancez une commande externe.exec
, mais les deux langues ont un flux de contrôle différent.&
démarre un sous-shell dans lequel la commande donnée est exécutée. Fourche + exec. Vous pouvez ' t simplement mettre&
sans commande précédente à exécuter.&
sur une ligne seule. Mais vous pouvez ' t. Cela ne ' t signifie " fourchette ici ". Cela signifie que " exécuter la commande précédente en arrière-plan dans un sous-shell ".