J'ai écrit un script simple. Quand je cours sh <myscriptname.sh>
, j'ai le bon résultat, mais quand je cours ./<myscriptname.sh>
, j'ai une erreur.
Quelle est la différence entre quand je fais sh
et ./
?
J'ai écrit un script simple. Quand je cours sh <myscriptname.sh>
, j'ai le bon résultat, mais quand je cours ./<myscriptname.sh>
, j'ai une erreur.
Quelle est la différence entre quand je fais sh
et ./
?
Réponses:
Lorsque vous exécutez un script en transmettant le nom de fichier au programme interpréteur de script, vous exécutez le programme interpréteur avec le script en tant qu'argument passé. Par exemple, cela ressemblerait au processus 'sh' avec l'argument 'filename.sh'. L' sh
interprète ouvre le fichier.
D'autre part, si vous exécutez le script lui-même, le système appelle le programme interprète spécifié et alimente le contenu des scripts. Dans ce cas, le processus ressemble à 'filename.sh' sans arguments.
Vous devriez vous assurer que vous avez une ligne bang:
#!/bin/bash
# bash script here
Une ligne éclatée est la toute première ligne du script et commence par les deux mêmes caractères #!
. Il s'agit de ce que le système lit lorsqu'il tente d'exécuter le script, puis le système le transmet au programme immédiatement après. Notez que cette ligne n’a rien à voir avec bash et fonctionne aussi bien pour python que pour perl, même si ce sont des langages très différents. Vous utiliseriez #!/usr/bin/python
par exemple, puis suiviez avec du code python.
Une fois que vous avez votre script, assurez-vous d’avoir défini les autorisations d’exécution:
chmod a+x filename.sh
Ensuite, vous pouvez exécuter le script en tant que processus propre:
./filename.sh
Ou placez le fichier dans un emplacement connu avec un nom de programme intéressant, comme /usr/sbin
par exemple:
sudo cp filename.sh /usr/sbin/program-name
program-name
Et c’est vraiment l’ avantage pratique d’utiliser la ligne bang avec les autorisations adéquates - tout est une 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'il veut l'exécuter. Par /usr/local/bin
exemple, le mettre en place et le rendre exécutable peut épargner énormément de chagrin à ceux qui essaient d’utiliser votre script. Ces programmes deviennent alors disponibles pour tous les utilisateurs de votre ordinateur.
C'est aussi bon pour l'identification. Si vous entrez dans le top
programme, un script exécuté sans la ligne bang n'aura que le nom de l'interprète c'est bash
-à- dire , perl
ou python
. Mais si un script est exécuté avec les autorisations appropriées, le nom du script s'affiche.
Remarque: Si vous souhaitez distribuer un script accessible à tous, créez une page de manuel et un package deb pour l'installer. Nous devons réduire le nombre de scripts aléatoires en ligne et augmenter le nombre de debs pouvant être désinstallés.
bash
, pas sh
.
PATH
.
/usr/local/bin
est probablement mieux alors /usr/sbin
- cela indique que le programme est local pour cette machine plutôt que de faire partie de la distribution.
La version courte:
sh
est l'interpréteur de ligne de commande (tiret).
Courir sh my_script
permet à dash d'interpréter le script.
./
essaie de trouver quel interprète utiliser, en regardant la première ligne. Par exemple #!/bin/bash
, ou même #!/bin/ruby
(par opposition à la course ruby my_script
).
./
ce qui trouve quelque chose, c'est la méthode d'exécution du système qui examine les deux premiers octets du fichier.
sh
et que le fichier contient un sha-bang, cela signifie-t-il que le sha-bang sera ignoré ou ouvrira-t-il le shell avec les sh
liens également et peut-être un autre shell ou que fera-t-il :)?
La différence que vous faites est,
avec sh
, vous exécutez un programme qui interprétera les lignes de votre script exactement comme vous les auriez dactylographiées sur l’invite interactive du terminal,
avec ./
vous faites un raccourci en supposant que le script est juste ici dans le répertoire courant que vous êtes assis dans et il sera exécutable (parce que , par exemple , vous avez émis chmod +x myscript.sh
), gain de temps précieux pour les temps futurs :-)
sh
le fichier ne doit pas nécessairement être exécutable.
Vous pouvez recevoir une erreur pour trois raisons principales:
chmod +x <myscriptname.sh>
pour résoudre ce problèmenoexec
"), /usr/local/bin
#!
ligne a une erreur, #!/bin/sh
ou#!/bin/bash
Si votre première ligne semble correcte mais ne fonctionne toujours pas, assurez-vous que le fichier ne comporte pas de fin de ligne DOS.
L'erreur ressemblerait à quelque chose comme ça:
$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory
Vous pouvez le fixer en cours d' exécution 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 d'une coquille très populaire. Mais obsolète et remplacé par d'autres. De nos jours, sh est lié à d’autres coques installées sur la machine. par exemple, j'ai bash misé là. L'exécution d'un shell à partir de sh déclenche généralement un mode 'compatibilité' avec le comportement 'shell' d'origine.
Donc, la solution est assez simple. Regardez ce qui se cache derrière la commande sh (ls -al / bin / sh), et mettez #! / Bin / any_you_find_there en première ligne (ou s'il y a quelque chose comme ça dans votre script, modifiez-le).
Et alternativement, il peut y avoir un bug dans le script lui-même. Comme la dépendance rencontrée par sh, mais pas l'interprète réellement utilisé.
mkdir ~/bin ; cp myscript.sh ~/bin/
echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ;
Non /usr/sbin
, c'est pour les outils administratifs non essentiels, /usr/local/bin
c'est un meilleur choix si vous ne voulez pas en avoir un ~/bin/
, mais il sudo
est préférable d' éviter autant que possible.
~/.profile
code par défaut contient déjà du code pour l'ajout ~/bin
, s'il existe, à PATH
. Sur une autre note, ne mettez pas d'extensions sur des scripts.
ls ~/bin/|wc -l = 428
) J'ai mis beaucoup de choses là-dedans;)
/bin
et /usr/bin
vous verrez qu'ils n'utilisent pas d'extensions.