J'ai lu ce qui suit dans cette question :
bash prend en charge un commutateur --posix, ce qui le rend plus compatible POSIX. Il essaie également d'imiter POSIX s'il est appelé en tant que sh .
La citation ci-dessus suppose qu'il /bin/sh
s'agit d'un lien pointant vers /bin/bash
.
Mais je ne comprends pas très bien ce que l'on entend par "invoqué comme sh" .
Disons que j'ai le script suivant qui s'appelle "script.sh":
#!/bin/bash
echo "Hello World"
Veuillez me dire dans chacun des cas suivants si le script sera exécuté en bash
mode normal ou en mode POSIX (supposez que j'ai exécuté les commandes suivantes dans un terminal en cours d'exécution bash
):
sh script.sh
bash script.sh
./script.sh
Maintenant, disons que j'ai le script suivant qui s'appelle "script.sh" (qui est comme le script ci-dessus mais sans le shebang):
echo "Hello World"
Veuillez me dire dans chacun des cas suivants si le script sera exécuté en bash
mode normal ou en mode POSIX (supposez que j'ai exécuté les commandes suivantes dans un terminal en cours d'exécution bash
):
sh script2.sh
bash script2.sh
./script2.sh
Réponses:
Seuls les cas 1 et 4 s'exécuteront en mode POSIX (en supposant que
sh
c'est bash et pas une autre implémentation de sh). Tout cas qui appelle explicitementbash
sans--posix
volonté, que ce soit du shebang ou non. Tout cas qui appelle explicitement lesh
sera. Le shebang n'est utilisé que lorsqu'aucun shell n'a déjà été explicitement démarré pour le script.Le cas 6, si votre terminal est en cours d'exécution
bash
, ne fonctionnera pas en mode POSIX et Bash l'invoquera en utilisant lui-même. Si le terminal était en cours d' exécution au lieu zsh, 6 cas serait également exécuter en mode POSIX. POSIX est ambigu quant à ce qui devrait se passer dans ce cas , et Bash et zsh y ont fait des choix différents. Bash invoque le script en utilisant lui-même, tandis que zsh l'utilisesh
(quel qu'il soit). D'autres obus varient également sur ce point.Une façon simple de savoir dans quel mode vous êtes est de créer votre corps de script:
qui échouera avec une erreur en mode POSIX , mais donnera des instructions d'utilisation pour l'
kill
extérieur. C'est une distinction facile et cela fonctionne à travers une longue gamme de versions de Bash remontant aussi loin que vous êtes susceptible de rencontrer.la source
bash
à s'exécuter en mode POSIX comme laPOSIXLY_CORRECT
variable d'environnement ouSHELLOPTS=posix
.[ -o posix ]
est un moyen plus évident de vérifier que vous exécutez en mode posix dans bash (pas dans d'autres shells (sauf yash), donc vous ne voudriez pas le faire dans unsh
script).POSIXLY_CORRECT=1 bash -c '[ -o posix ] && echo yes'
sortiesyes
`Le « invoqué comme » fait référence à quoi que ce soit que le processus de démarrage Bash met dans son argument de ligne de commande « zeroth »,
argv[0]
.Lorsqu'un programme est démarré avec les
exec*()
appels système , ils ne connaissent pas vraiment le nom du fichier binaire contenant le programme, mais à la place, le processus d'appel est libre d'y mettre ce qu'il veut. Habituellement, bien sûr, le nom est tiré du système de fichiers, donc si vous exécutez/bin/sh
, c'est ce qui est mis là. Et si/bin/sh
c'est Bash, il ne doit pas nécessairement être un lien symbolique, il peut s'agir d'un lien dur ou simplement d'une autre copie du programme shell.Comme exemple de définition du "nom du programme", la
exec
commande de Bash peut définir l'argument zéro avec l'-a
option. (On pourrait faire de même avec Perl, ou directement avec C, etc.)Voici
myname
un programme C simple qui affiche simplement son argument zéro, le nom qu'il voit lui-même:La source:
Mais, pour répondre aux questions numérotées ...
(1 & 4) en cours d'exécution
sh somescript
exécutera tout ce qui sesh
trouve sur votrePATH
, probablement/bin/sh
mais peut-être quelque chose comme/usr/xpg4/bin/sh
.sh
.sh
, mais il fonctionne en mode "SH compatible", qui vise à être compatible avec le shell Bourne et est subtilement différent du mode conforme POSIX complet dans ces deux shells. .(2 & 5) La course
bash somescript
se déroulera en mode Bash normal (encore une fois, cela dépend bien sûr de ce quebash
vousPATH
êtes.)(3) Ici, le nom du script est donné directement à l'appel système à la place du fichier programme. Le noyau lit la ligne de hachage et l'utilise pour exécuter le script.
(6) C'est le complexe. Il est similaire à (3), mais l'appel système pour démarrer le programme échoue (
ENOEXEC (Exec format error)
), car il n'y a pas de ligne de hachage. Ce qui se passe ensuite dépend de si le shell que vous exécutez est lui - même en mode POSIX. POSIX requiert qu'un shell conforme à POSIX se comporte d'une manière spécifique en réponse àENOEXEC
. Cependant, il existe une certaine marge de manœuvre dans "une commande équivalente à l'invocation d'un shell", ce qui signifie que différents shells font des choses différentes./bin/sh
avec le nom du script inséré avant les autres arguments comme premier argument de ligne de commande. Le shell Z, le shell Almquist et le shell Korn (tentent) d'invoquer un shell conforme POSIX à force de supposer que le/bin/sh
programme en est un.la source
int main(int argc, char *argv[]){printf("I am %s\n",argv[0]);}
Le shell exécuté est soit celui appelé dans la ligne de commande, soit celui dans le shebang (si la ligne de commande ne le spécifie pas).
Ainsi, les versions 1 et 4 fonctionneront avec
sh
, 2 et 5 avec bash et 6 peuvent ne pas fonctionner si vous utilisez sh (et quelques autres) de manière interactive. Bash démarre le script. Ksh aussi. Zsh démarre comme sh.Seuls ceux démarrés comme
sh
utiliseront l'option posix si bash est lié à/bin/sh
.Ajoutez cette ligne à votre script pour détecter si une version bash ksh ou zsh l'exécute:
la source