Les fonctions sexécutent-elles en tant que sous-processus dans Bash?

Dans Guide avancé des scripts Bash , dans exemple 27-4 , 7ème ligne à partir du bas, jai lu ceci:

Une fonction sexécute comme un sous-processus.

Jai fait un test dans Bash, et il semble que la déclaration ci-dessus soit fausse.

Recherche sur ce site, Bash Man, et mon moteur de recherche n’apportent aucune lumière.

Avez-vous la réponse et souhaitez-vous expliquer?

Commentaires

  • Comme indiqué, ce guide est trompeur à lextrême. Je recommande plutôt le Guide Wooledge Bash .
  • Un fait important est que  » Bash  » évite de créer des sous-shell. Ils sont chers, ont votre propre environnement, et ceux-ci affectent les performances du script ainsi que la façon dont le code circule (souvent, de manière peu pratique, afin de gérer leurs particularités). Létat actuel de Bash est le produit dune évolution, une évolution du code. Je veux dire, la première version de Bash utilise plus de sous-shell *** que la version actuelle. Ce genre dincohérence semble raisonnable. *** si vous voulez une preuve, je ne peux ‘ vous donner. Je ‘ lai dérivé de pages Web, de commentaires … Jai ‘ lu cette déclaration quelque part il y a quelque temps.

Réponse

Le Guide des scripts Bash avancés nest pas toujours fiable et ses exemples de scripts contiennent des pratiques obsolètes telles que lutilisation du effectivement obsolète les backticks pour la substitution de commandes, cest-à-dire `command` plutôt que $(command).

Dans ce cas particulier, cest manifestement incorrect.

La section sur les Fonctions Shell dans le (canonique) Bash le manuel déclare définitivement que

Les fonctions du shell sont exécutées dans le contexte actuel du shell; aucun nouveau processus nest créé pour les interpréter.

Commentaires

  •  » Le guide avancé des scripts Bash nest généralement pas fiable  » Très vrai.
  • Pouvez-vous donner des références pour soutenir votre première phrase?
  • @WillVousden à quoi ressemblerait une référence ici? Un tas dexemples des lacunes techniques du guide ‘? Un document où les experts de la communauté bash ont précédemment noté quil nest pas fiable? Cela aiderait-il si un membre de stackoverflow avec un badge or dans bash venait daccepter dans un commentaire? : p
  • @WillVousden Je ne ‘ pas penser que ce que vous voulez existe sous une forme fiable. Mendel Cooper a mis à jour et corrigé des problèmes avec le guide dans le passé, mais il ny a pas de traqueur de bogues public ou de liste derrata. (Cest peut-être la déclaration la plus accablante que je puisse faire.) Ainsi, lorsque nous trouvons une faille (perçue ou réelle), tout ce que nous pouvons faire est denvoyer un e-mail à lauteur et espérer le meilleur.
  • @WillVousden, .. .si vous voulez un historique de la durée du consensus dans le canal freenode #bash selon lequel lABS devrait être évité, voir wooledge.org/ ~ greybot / meta / abs – le deuxième champ de chaque ligne est lhorodatage et le premier est le nom dutilisateur; ‘ je vais espérer que laffirmation selon laquelle les noms dutilisateur en question sont des personnes très respectées suffira.

Réponse

Les fonctions daccolades seront exécutées dans le processus du shell appelant, à moins quelles naient besoin de leur propre sous-shell qui est:

  • lorsque vous les exécutez en arrière-plan avec &
  • lorsque vous les exécutez en tant que lien dans un pipeline

Redirections ou env supplémentaires. les variables ne « t forceront pas un nouveau sous-shell:

hw(){ echo hello world from $BASHPID echo var=$var } var=42 hw >&2 echo $BASHPID #unexports var=42 and restores stdout here 

Si vous définissez la fonction avec des parenthèses au lieu de curlies:

hw()( echo hello world from $BASHPID ) hw echo $BASHPID 

il sera toujours exécuté dans un nouveau processus.

La substitution de commande $() crée également toujours des processus dans bash (mais pas dans ksh si vous exécutez des builtins à lintérieur).

Commentaires

  • Je nai pas ‘ je sais f() (...) est autorisé. Existe-t-il dautres définitions que {...} et (...)? Dans Bash, je ‘ m pas encore dans les autres.
  • @tomas Vous pouvez utiliser la syntaxe function hw { echo hello world; } (pas besoin de () si vous saisissez function et que vous pouvez spécifier des redirections juste après la dernière } ou ) comme dans hw(){ echo error; } >&2. Cela ‘ à ce sujet.
  • Ceci est la réponse à laquelle jai immédiatement pensé, et elle est absolument correcte.Elle devrait être votée comme la bonne réponse. f()(...) exécute toujours son propre shell, alors que f(){...} ne le fait pas.
  • Les fonctions NB bash acceptent toutes les commandes composées, donc foo() [[ x = x ]] est également une définition de fonction valide. Cependant, si vous regardez la fonction avec type foo vous ‘ vous verrez quil sagit toujours de sucre syntaxique pour foo() { [[ x = x ]]; }. Il en va de même pour les fonctions de sous-shell: bar() ( : ) devient bar() { ( : ); }.
  • @kojiro nice +1. ‘ je ne savais pas que

Answer

La commande dans La question de cet exemple ressemble à:

echo ${arrayZ[@]/%e/$(replacement)} 

Lexemple suivant indique:

# $( ... ) is command substitution. # A function runs as a sub-process. 

Étant une œuvre de bienfaisance pour ABS Guide, ce quils voulaient apparemment écrire, cest que la fonction sexécute dans une substitution de commande et la commande à lintérieur dune substitution de commande sexécute dans un sous-shell .

Commentaires

  • Ce ‘ est très trompeur. Merci pour votre interprétation.
  • @tomas  » très trompeur.  » Oui, très. Contrairement au Guide ABS, le Wiki de Greg ‘ est une excellente source d’informations de bash avancées.
  • Acclamations. Quelle est ‘ votre opinion sur celui-ci: wiki.bash-hackers.org/start ?
  • @tomas Je nai aucune connaissance de première main de celui-ci.
  • @tomas, … ma propre opinion sur le wiki bash-hackers est quil ‘ est une excellente source. Je nai ‘ pas été à travers cela de manière aussi complète que jai le wiki Wooledge, mais il a tendance à être précis et écrit avec précision.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *