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

62

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

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

    
posée mr_eclair 23.01.2011 - 16:16
la source

6 réponses

60

Lorsque vous exécutez un script en transmettant le nom de fichier au programme d'interpréteur 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 'nomfichier.sh'. L'interpréteur sh ouvre le fichier.

D'autre part, si vous exécutez le script lui-même, le système appelle le programme d'interpréteur 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 de bang:

#!/bin/bash
# bash script here

Une ligne de bang est la première ligne du script et commence par les deux mêmes caractères #! , ce que le système lit lorsqu'il essaie d'exécuter le script, puis le système passe le script 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 les langages sont très différents. Vous utiliseriez #!/usr/bin/python par exemple et vous suivriez ensuite avec du code python.

Une fois que vous avez votre script, assurez-vous d’avoir défini les droits d’exécution:

chmod a+x filename.sh

Ensuite, vous pouvez exécuter le script en tant que processus distinct:

./filename.sh

Ou placez le fichier dans un emplacement connu avec un nom de programme intéressant, tel que /usr/sbin et exécuté de n'importe où:

sudo cp filename.sh /usr/sbin/program-name
program-name

Et c’est vraiment le avantage pratique d’utiliser la ligne bang avec les bonnes autorisations - tout ce qui concerne le déploiement . Il est très difficile d'inciter les utilisateurs à exécuter un script s'ils doivent se souvenir de quel programme exécuter le script. N'oubliez pas de donner un chemin complet au script chaque fois qu'il veut l'exécuter. Le fait de le placer dans /usr/local/bin par exemple et de le rendre exécutable peut permettre d’éviter énormément de chagrin aux personnes qui essaient d’utiliser votre script. Ces programmes deviennent alors disponibles pour tous les utilisateurs de sur votre ordinateur.

C'est aussi bon pour l'identification. Si vous allez dans le programme top , un script exécuté sans la ligne bang aura simplement le nom de l'interpréteur, c'est-à-dire bash , perl ou python . Mais si un script est exécuté avec les bonnes autorisations, 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 deb pouvant être désinstallés.

    
réponse donnée Martin Owens -doctormo- 23.01.2011 - 16:31
la source
34

La version courte:

  • sh est l'interpréteur de ligne de commande (dash).
    L'exécution de sh my_script permet à dash d'interpréter le script.

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

réponse donnée Stefano Palazzo 23.01.2011 - 16:44
la source
3

Vous faites la différence,

  • 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 est juste ici dans le répertoire dans lequel vous vous trouvez ET il sera exécutable (parce que par exemple vous avez émis chmod +x myscript.sh ), en sauvegardant vous avez un temps précieux pour les temps futurs: -)

réponse donnée meduz 23.01.2011 - 23:13
la source
3

Il y a trois raisons principales pour lesquelles vous pourriez avoir une erreur:

  • le fichier n'est pas exécutable
    exécutez chmod +x <myscriptname.sh> pour résoudre ce problème
  • la partition ne permet pas d’exécuter des scripts (est monté " noexec ")
    copier 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 n'a pas de terminaison de ligne DOS.

L’erreur ressemblerait à ceci:

$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory

Vous pouvez résoudre le problème en exécutant dos2unix <myscriptname.sh> ou, si vous ne l’avez pas, dans perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh> .

    
réponse donnée Mikel 03.02.2011 - 23:03
la source
0

Et la réponse est que sh est le nom du shell très populaire. Mais dépassé et remplacé par d'autres. De nos jours, sh est lié à d'autres shells installés sur la machine. par exemple. J'ai bash posé là-bas. L'exécution de n'importe quel shell à partir de sh déclenche généralement un mode de "compatibilité" avec le comportement "shell" d'origine.

La solution est donc assez simple. Regardez ce qui se trouve derrière la commande sh (ls -al / bin / sh), et mettez #! / Bin / importe_you_find_there en 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 rencontrée par sh, mais pas l’interpréteur réellement utilisé.

    
réponse donnée przemo_li 23.01.2011 - 18:09
la source
0
mkdir ~/bin ; cp myscript.sh ~/bin/

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

Pas /usr/sbin , que pour les outils d'administration non essentiels, /usr/local/bin est un meilleur choix si vous ne voulez pas avoir un ~/bin/ , mais en évitant sudo autant que possible est conseillé.

    
réponse donnée Joey1978 24.01.2011 - 08:25
la source

Lire d'autres questions sur les étiquettes