Il y a ces deux noms :un sous-shell et un child-shell .
Oui, un processus enfant sera lancé par l'un des éléments suivants :
sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat
Sont-ils tous équivalents et partagent-ils le même nom ? Partagent-ils tous les mêmes propriétés ?
POSIX a cette définition :
Un environnement d'exécution shell se compose de ….
Mais le dernier paragraphe du lien ci-dessus contient ceci :
Un environnement de sous-shell doit être créé en tant que doublon de l'environnement du shell, sauf que les interruptions de signal qui ne sont pas ignorées doivent être définies sur l'action par défaut.
Et spécialement :
La substitution de commandes, les commandes regroupées entre parenthèses et les listes asynchrones doivent être exécutées dans un environnement de sous-shell. De plus, chaque commande d'un pipeline multi-commandes se trouve dans un environnement de sous-shell ; ….
Le sh -c 'echo "Hello"'
n'est pas inclus ici, devrait-il également être appelé un sous-shell ?
Réponse acceptée :
Un sous-shell dupliqué la coque existante. Il a les mêmes variables¹, les mêmes fonctions, les mêmes options, etc. Sous le capot, un sous-shell est créé avec le fork
appel système² ; le processus enfant continue à faire ce qu'on attend de lui pendant que le parent attend (par exemple, $(…)
) ou continue sa vie (par exemple, … &
) ou fait autrement ce qu'on attend d'elle (par exemple, … | …
).
sh -c …
ne crée pas de sous-shell. Il lance un autre programme. Ce programme se trouve être un shell, mais ce n'est qu'une coïncidence. Le programme peut même être un shell différent (par exemple, si vous exécutez sh -c …
de bash, et sh
est un tiret), c'est-à-dire un programme complètement différent qui se trouve avoir des similitudes significatives dans son comportement. Sous le capot, lancer une commande externe (sh
ou tout autre) appelle le fork
appel système puis le execve
appel système pour remplacer le programme shell dans le sous-processus par un autre programme (ici sh
).
¹ Y compris $$
, mais en excluant certaines variables spécifiques au shell telles que bash et le BASHPID
de mksh .
² Au moins, c'est la mise en œuvre traditionnelle et habituelle. Les coquilles peuvent optimiser la fourche si elles peuvent imiter le comportement autrement.
Pages de manuel pertinentes :fork(2), execve(2).