3 votes

Pourquoi le shebang n'entraîne-t-il pas le fork d'un programme comme il le devrait ?

J'ai toujours déclaré la ligne du shebang #!/bin/bash dans mon Shell Shell. Récemment, lorsque j'ai appelé un Shell qui contient un exit appel, ça a tué mon terminal. D'habitude, il tue le processus de bifurcation et retourne à l'invite de mon terminal. Qu'est-ce qui a pu se passer pour arrêter la bifurcation ?

EDIT

$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin10.0)
  • J'invoque habituellement script en utilisant . script_path ou via un lien symbolique vers le script.

1 votes

Comment l'avez-vous invoqué ? Quelle est la version de bash ?

6voto

Damian Powell Points 315

Puisque le sourcing d'un script à l'aide de . fait en sorte qu'il soit exécuté dans le Shell actuel, un exit fait sortir le Shell actuel. Vous pouvez utiliser return pour revenir d'un script sourcé ainsi que d'une fonction. Vous ne pouvez pas revenir d'un script qui a été exécuté directement.

Afin de travailler avec ces contraintes, vous pouvez mettre un test conditionnel dans votre script pour faire la bonne chose selon qu'il est sourcé ou exécuté directement.

Comme la première ligne après le shebang :

called=$_

Au point où vous voulez sortir ou revenir :

[[ $called != $0 ]] && exit || return

0 votes

Une astuce intelligente. Très utile pour les scripts qui doivent être sourcés pour fonctionner correctement, comme Python. virtualenv activate scripts.

0 votes

@hobs : J'inclus la ligne suivante comme première ligne au lieu d'un shebang dans tous les scripts qui doivent être sourcés : [[ $_ != $0 ]] || { echo "This file must be sourced to have any effect."; exit 1; }

0 votes

Je crois que c'est à l'envers - cela devrait être [["$called" = "$0"]] &&exit ||return .(P.S.Vous devriez toujours citer toutes les références de variables Shell à moins que vous n'ayez une bonne raison de ne pas le faire, et vous êtes sûr Une autre approche qui est (sans doute) plus intuitive (et qui demande moins de prise de tête) est la suivante return2>/dev/null ||exit .

5voto

MDMoore313 Points 1038

Le shebang ne provoque jamais le bifurcation d'un processus.  Il ne fait pas tout ce qui est À MOINS que le script soit exécutable et qu'il soit invoqué de telle manière qu'il amène le système à évaluer le shebang pour voir avec quel programme/script exécuter le script.

Si, par exemple, vous étiez déjà sous bash, et que vous exécutiez le script avec le paramètre source alors le script serait exécuté à l'intérieur du script que vous êtes en train d'exécuter, et la commande exit affecterait ce processus Shell, plutôt que d'être un nouveau processus Shell qui a été terminé.

Si vous avez un fichier script que vous voulez exécuter, vous devez le rendre exécutable avec la commande suivante :

chmod +x script

Ensuite, si vous voulez exécuter le script, et si nous supposons que le fichier script se trouve dans le répertoire courant, vous utilisez la commande suivante :

./script

Notez que c'est très différent de . script qui est juste une notation abrégée pour source script .

Le site ./script est un chemin d'accès relatif au fichier script, ce qui signifie rechercher dans le répertoire courant pour trouver le fichier script 'script' et ensuite l'exécuter - ce qui ne fonctionne que si le fichier script est exécutable.

Si vous avez un fichier script qui n'est PAS exécutable, alors vous pouvez l'invoquer avec :

bash script

Mais dans ce cas, vous spécifiez quel Shell exécuter et la ligne shebang est ignorée.

0 votes

Merci de votre réponse. Je l'exécute par ". script". La chose étrange se produit par intermittence. Comme je l'ai dit, cela n'arrivait pas avant.

1 votes

Le . est un raccourci pour la commande source. Si vous voulez qu'elle fork, vous devez rendre le script exécutable, et ensuite le mettre dans votre chemin quelque part, puis vous pouvez l'exécuter en tapant le nom, ou s'il n'est pas dans le chemin, en tapant un chemin vers le script.

4voto

Le shebang ne provoque pas le fork d'un programme ; le fait que le processus fork ou non dépend de la façon dont le script est exécuté. Le sourcing du script le fera s'exécuter dans l'interpréteur actuel, et l'utilisation de la commande exec remplacera entièrement le processus actuel.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X