web-dev-qa-db-fra.com

Quelle est la différence entre ./ et sh pour exécuter un script?

J'ai écrit un script simple. Quand j'ai lancé sh <myscriptname.sh>, j'ai obtenu le bon résultat, mais quand j'ai lancé ./<myscriptname.sh>, j'ai eu une erreur.

Quelle est la différence entre quand je fais sh et ./?

70
mr_eclair

Lorsque vous exécutez un script en transmettant le nom de fichier au programme d'interprétation de script, vous exécutez le programme d'interprétation avec le script en tant qu'argument transmis. Par exemple, cela ressemblerait au processus "sh" avec l'argument "filename.sh". L'interprète shest en train d'ouvrir le fichier.

Par ailleurs, 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 le toute première ligne dans le script et commence par les deux mêmes caractères #!. Il s’agit de ce que le système lit quand il essaie d’exécuter le script, puis il le transmet au programme immédiatement après. Notez que cette ligne n'a rien à voir avec bash et fonctionne aussi bien pour python et Perl, même si ce sont des langages très différents. Vous utiliseriez par exemple #!/usr/bin/python et le suivriez avec le 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 Nice, comme /usr/sbin, et exécutez-le n'importe où:

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 - il s’agit du 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. Par exemple, le mettre dans /usr/local/bin 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 allez dans le programme topname__, un script exécuté sans la ligne bang n'aura que le nom de l'interpréteur, à savoir bashname__, Perlou pythonname__. 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 paquet 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.

66

La version courte:

  • sh est l'interpréteur de ligne de commande (tiret).
    Lancer sh my_script fait en sorte que dash interprète le script.

  • ./ essaie de trouver quel interpréteur utiliser en regardant la première ligne. Par exemple. #!/bin/bash, ou même #!/bin/Ruby (comme indiqué par l'exécution de Ruby my_script).

41
Stefano Palazzo

La différence que vous faites est,

  • avec sh, vous exécutez un programme qui interprétera les lignes de votre script exactement comme si vous les aviez tapées sur l'invite interactive du terminal,

  • avec ./ vous créez un raccourci en partant du principe que le script se trouve exactement dans le répertoire actuel dans lequel vous êtes assis ET qu'il sera exécutable (parce que vous avez par exemple émis chmod +x myscript.sh), vous permettant ainsi de gagner un temps précieux :-)

5
meduz

Vous pouvez obtenir une erreur pour trois raisons principales:

  • le fichier n'est pas exécutable
    lancez chmod +x <myscriptname.sh> pour résoudre ce problème
  • la partition n'autorise pas l'exécution de scripts (est monté "noexec")
    Copiez le script dans /usr/local/bin
  • la ligne #! a une erreur
    assurez-vous que la première ligne est #!/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 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>.

3
Mikel

Et la réponse est que sh est le nom de Shell 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. Je l'ai mis là. L'exécution d'un shell à partir de sh déclenche généralement un mode de compatibilité avec le comportement d'origine du shell.

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é.

0
przemo_li
mkdir ~/bin ; cp myscript.sh ~/bin/

echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ; 

/usr/sbin n'est pas, c'est pour les outils administratifs non essentiels, /usr/local/bin est un meilleur choix si vous ne voulez pas avoir un ~/bin/, mais il est préférable d'éviter Sudoautant que possible.

0
Joey1978