web-dev-qa-db-fra.com

$ () Est-il un sous-shell?

Je comprends que la syntaxe du sous-shell est (<commands...>), Est-ce que $() est juste un sous-shell à partir duquel vous pouvez récupérer les valeurs des variables?

Remarque: Cela s'applique à bash 4.4 basé sur une formulation différente dans leur documentation.

55
leeand00

$(…) est un sous-shell par définition: c'est une copie de l'état d'exécution du Shell¹, et les modifications apportées à l'état effectué dans le sous-shell n'ont aucun impact sur le parent. Un sous-shell est généralement implémenté par forking un nouveau processus (mais certains shells peuvent l'optimiser dans certains cas).

Ce n'est pas un sous-shell à partir duquel vous pouvez récupérer des valeurs de variable. Si les modifications apportées aux variables avaient un impact sur le parent, ce ne serait pas un sous-shell. C'est un sous-shell dont la sortie le parent peut récupérer. Le sous-shell créé par $(…) a sa sortie standard définie sur un canal, et le parent lit à partir de ce canal et collecte la sortie.

Il existe plusieurs autres constructions qui créent un sous-shell. Je pense que c'est la liste complète de bash:

  • Sous-shell pour regroupement : ( … ) Ne fait que créer un sous-shell et attendre qu'il se termine). Comparez avec { … } Qui regroupe les commandes uniquement à des fins syntaxiques et ne crée pas de sous-shell.
  • Contexte : … & Crée un sous-shell et n'attend pas qu'il se termine.
  • Pipeline : … | … Crée deux sous-coquilles, une pour le côté gauche et une pour le côté droit, et attend que les deux se terminent. Le shell crée un tuyau et connecte la sortie standard du côté gauche à l'extrémité d'écriture du tuyau et l'entrée standard du côté droit à l'extrémité de lecture. Dans certains shells (ksh88, ksh93, zsh, bash avec l'option lastpipe définie et effective), le côté droit s'exécute dans le shell d'origine, de sorte que la construction du pipeline n'en crée qu'un sous-coquille.
  • Substitution de commande : $(…) (également orthographié `…`) Crée un sous-shell avec sa sortie standard définie sur un canal, recueille la sortie dans le parent et se développe vers cette sortie , moins ses nouvelles lignes de fin. (Et la sortie peut encore être divisée et globulée, mais c'est une autre histoire.)
  • Substitution de processus : <(…) crée un sous-shell avec sa sortie standard définie sur un tube et se développe au nom du tube. Le parent (ou un autre processus) peut ouvrir le canal pour communiquer avec le sous-shell. >(…) fait de même mais avec le tube sur l'entrée standard.
  • Coprocess : coproc … Crée un sous-shell et n'attend pas qu'il se termine. L'entrée et la sortie standard du sous-boîtier sont chacune définies sur un tuyau, le parent étant connecté à l'autre extrémité de chaque tuyau.

¹ Par opposition à l'exécution d'un shell séparé .

Depuis la page de manuel bash (1) dans la version 4.4 de bash, section "EXPANSION", sous-section "Substitution de commande":

Bash effectue l'expansion en exécutant command dans un environnement de sous-shell [...]

Oui, ( commands... ) Est un sous-shell bash qui exécutera commands... Dans un autre processus.

La seule différence lorsque vous avez $( commands... ) est que cette partie du code sera remplacée après l'exécution de commands... Par tout ce que commands... A écrit dans stdout.

5
Iskustvo