J'ai écrit un simple script. Lorsque j'exécute sh <myscriptname.sh>
j'ai obtenu le résultat correct, mais quand j'exécute ./<myscriptname.sh>
j'ai eu une erreur.
Quelle est la différence entre le moment où je fais sh
y ./
?
J'ai écrit un simple script. Lorsque j'exécute sh <myscriptname.sh>
j'ai obtenu le résultat correct, mais quand j'exécute ./<myscriptname.sh>
j'ai eu une erreur.
Quelle est la différence entre le moment où je fais sh
y ./
?
Lorsque vous exécutez un script en passant le nom du fichier au programme interprète script, vous exécutez le programme interprète avec le script comme argument passé dans celui-ci. Par exemple, cela ressemblerait au processus 'sh' avec l'argument 'filename.sh'. Le site sh
l'interpréteur ouvre le fichier.
Par contre, si vous exécutez le script lui-même, le système fait appel au programme interprète spécifié et alimente le contenu du script. Dans ce cas, le processus ressemble à 'nomfichier.sh' sans arguments.
Vous devez vous assurer que vous avez une ligne de bang :
#!/bin/bash
# bash script here
Une ligne de bang est le toute première ligne dans le script et commence par les deux mêmes caractères #!
, ce sont ce que le système lit quand il essaie d'exécuter le script et ensuite le système passe le script au programme immédiatement après. Notez que cette ligne n'a rien à voir avec bash et fonctionne tout aussi bien pour Python et perl, même s'il s'agit de langages très différents. Vous utiliseriez #!/usr/bin/python
par exemple, puis de le suivre avec du code Python.
Une fois que vous avez votre script, assurez-vous que vous avez défini les autorisations d'exécution :
chmod a+x filename.sh
Vous pouvez alors exécuter le script comme son propre processus :
./filename.sh
Ou bien mettez le fichier dans un endroit connu avec un nom de programme sympa, comme /usr/sbin
et de fonctionner de n'importe où :
sudo cp filename.sh /usr/sbin/program-name
program-name
Et c'est vraiment le pratique l'avantage d'utiliser la ligne bang avec les bonnes autorisations - tout est question de déploiement . Il est très difficile d'amener les utilisateurs à exécuter un script s'ils doivent se rappeler avec quel programme exécuter le script. N'oubliez pas de donner un chemin complet au script chaque fois qu'ils veulent l'exécuter. Alors qu'en le mettant dans /usr/local/bin
par exemple, et le rendre exécutable, peut épargner beaucoup de soucis aux personnes qui essaient d'utiliser votre script. Ces programmes deviennent alors disponibles pour tous utilisateurs sur votre ordinateur.
C'est aussi bon pour l'identification. Si vous allez dans le top
un script exécuté sans la ligne bang aura juste le nom de l'interpréteur i.e. bash
, perl
o python
. Mais si un script est exécuté avec les bonnes permissions, alors le nom du script apparaît.
Note : Si vous voulez distribuer un script accessible à tous, alors veuillez créer une page de manuel et un paquet deb pour l'installer. Nous devons réduire le nombre de script aléatoires en ligne et augmenter le nombre de debs qui peuvent être désinstallés.
La version courte :
sh
est l'interpréteur de ligne de commande (tiret).
Running sh my_script
fait interpréter à Dash le script.
./
essaie de trouver quel interpréteur utiliser, en regardant la première ligne. Par exemple #!/bin/bash
ou encore #!/bin/ruby
(par opposition à l'exécution ruby my_script
).
La différence que vous faites est,
avec sh
vous exécutez un programme qui interprétera les lignes de votre script comme si vous les aviez tapées à l'invite interactive du terminal,
avec ./
vous créez un raccourci en supposant que le script se trouve juste ici dans le répertoire actuel dans lequel vous vous trouvez ET qu'il sera exécutable (parce que par exemple vous avez émis chmod +x myscript.sh
), ce qui vous fera gagner un temps précieux pour les prochaines fois :-)
Il y a trois raisons principales pour lesquelles vous pouvez obtenir une erreur :
chmod +x <myscriptname.sh>
pour réparer celanoexec
")/usr/local/bin
#!
La ligne a une erreur#!/bin/sh
o #!/bin/bash
Si votre première ligne semble correcte, mais ne fonctionne toujours pas, vérifiez que le fichier ne comporte pas de fins de ligne DOS.
L'erreur ressemblerait à ceci :
$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory
Vous pouvez le réparer en exécutant dos2unix <myscriptname.sh>
ou si vous ne l'avez pas,perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>
.
Et la réponse est que sh est le nom du très populaire Shell. Mais il est dépassé et remplacé par d'autres. Aujourd'hui, sh est lié à d'autres shells installés sur la machine. Par exemple, j'ai installé bash. L'exécution de n'importe quel Shell à partir de sh déclenche généralement un mode de 'compatibilité' avec le comportement original de 'Shell'.
La solution est donc très simple. Regardez ce qu'il y a derrière la commande sh (ls -al /bin/sh), et mettez #!/bin/quelque chose que vous trouvez comme première ligne (ou s'il y a quelque chose comme ça dans votre script éditez-le).
Et alternativement, il peut y avoir un bug dans le script lui-même. Comme la dépendance qui est satisfaite par sh, mais pas l'interprète qui est réellement utilisé.
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.