Un sous-shell est-il la même chose qu'un shell enfant

11

Il y a ces deux noms: un sous - shell et un shell enfant .

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? Tous partagent-ils les mêmes propriétés?


POSIX a cette définition :

Un environnement d'exécution de shell se compose de ....

Mais le dernier paragraphe du lien ci-dessus a ceci:

Un environnement de sous-shell doit être créé en tant que doublon de l'environnement de 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 sous-shell; ....

Le sh -c 'echo "Hello"'n'est pas inclus là-bas, cela devrait-il aussi être appelé un sous-shell?

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

Réponses:

14

Un sous-shell duplique le shell existant. Il a les mêmes variables¹, les mêmes fonctions, les mêmes options, etc. Sous le capot, un sous-shell est créé avec l' forkappel 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 ce qu'on attend de lui (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 …depuis bash, et shest dash), c'est-à-dire un programme complètement différent qui se trouve avoir des similitudes significatives dans son comportement. Sous le capot, le lancement d'une commande externe ( shou de toute autre) appelle l' forkappel système, puis l' execveappel système pour remplacer le programme shell dans le sous-processus par un autre programme (ici sh).

¹ Incluant $$, mais excluant certaines variables spécifiques au shell telles que bash et mksh BASHPID.
² Du 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) .

Gilles 'SO- arrête d'être méchant'
la source
Merci. À quoi appartient l'exécution d'un script bash avec bash shebang?
Tim
@Tim Même chose que sh -c: c'est un sous-processus qui se trouve par hasard être un shell.
Gilles 'SO- arrête d'être méchant'
(1) "le lancement d'une commande externe (sh ou tout autre) appelle l'appel système fork puis l'appel système execve pour remplacer le programme shell dans le sous-processus par un autre programme (ici sh)." Est-il juste que fork crée d'abord un sous-shell puis exécute le remplacement du sous-shell par le programme externe? Donc, dans les deux cas de votre réponse, un sous-shell est toujours créé? (2) "Un sous-shell qui duplique le shell existant." Qu'est-ce que ça veut dire?
Tim
(3) dans bash -c <command>, après fork du shell puis execve bash -c <command>, un shell bash est créé. Ensuite, l'appel système est-il utilisé pour exécuter à <command>nouveau le fork du shell bash et l'exécuter <command>?
Tim
2
@cuonglm «Child shell» n'est pas un terme technique ayant une signification spécifique, contrairement à «subshell». Si c'est un shell qui est un enfant, alors c'est un shell enfant, en suivant les règles habituelles de l'anglais.
Gilles 'SO- arrête d'être méchant'
1

Un environnement sous-shell n'a pas besoin de vivre dans un processus séparé, il a juste besoin de dupliquer l'environnement d'exécution actuel. En ksh93cela se fait par un virtual sub-shellmécanisme qui n'appelle pas fork(). Cela rend ksh93 très rapide sur des plates-formes archaïques Win-DOS, comme Win-DOSc'est extrêmement lent avec le forking.

sh -c cmd de l'autre côté crée un nouveau processus avec le shell par défaut qui n'a pas besoin d'être le même que votre shell interactif actuel.

Même lorsque shet votre shell actuel sont identiques, cela ne duplique pas l'environnement d'exécution et ne crée donc pas de sub-shell.

schily
la source
Donc, dans d'autres coquilles sauf ksh93, la sous-coquille est une coquille enfant, n'est-ce pas?
cuonglm
Je ne connais aucune autre implémentation qui implémente des sous-coquilles virtuelles aujourd'hui.
schily