Quel type de chemin en shebang est plus préférable?

20

Dans les scripts, la première ligne doit spécifier le chemin d'accès à l'interpréteur.
Mais sur différents serveurs Linux, Unix ou BSD, ce chemin pourrait être différent.

Quoi de plus préférable?

#!/usr/bin/env bash 

ou

#!/bin/bash 
Roman Ivanov
la source

Réponses:

22

Si vous souhaitez utiliser la version installée par le système d'un interpréteur donné installé dans un emplacement standard, utilisez le chemin direct. Si vous souhaitez utiliser la version de l'interpréteur qui apparaît en premier dans l'utilisateur $PATH, utilisez #!/usr/bin/env ....

La envcommande appelle une commande spécifiée, vous permettant de définir ou de désactiver les variables d'environnement:

env FOO=BAR do-something
env DISPLAY=:0.0 xterm -ls &

Si vous ne spécifiez aucune variable d'environnement ou d'autres options, il appellera simplement la commande nommée. (L'utiliser de cette façon est sans doute un peu un hack.)

Le but d'écrire le shebang comme

#!/usr/bin/env interp

est d'invoquer ce qui interpapparaît en premier $PATH.

Cela signifie que vous ne devez pas savoir, lors de l' écriture du script, exactement où interpest ( par exemple, si elle pouvait être soit /bin, /usr/binou /usr/local/bin). Bien sûr , vous ne devez savoir envest /usr/bin/env, mais qui semble être raisonnablement universelle.

L'avantage est qu'il invoque la version de l'interpréteur qui apparaît en premier dans l'utilisateur $PATH. L' inconvénient est qu'il appelle la version de l'interpréteur qui apparaît en premier dans l'utilisateur $PATH.

Par exemple, supposons que j'ai installé une version personnelle de perlsous mon répertoire personnel, as $HOME/bin/perl, et que je l'ai $HOME/binà l'avant de mon $PATH. Si je lance un script dont le shebang est

#!/usr/bin/env perl

alors il va être exécuté avec mon propre perlexécutable installé - ce qui pourrait ne pas être une bonne chose. L'auteur du script ne l'a probablement pas testé avec le Perl de pointe que j'ai construit à partir des sources il y a un mois.

Pour quelque chose comme Perl ou Bash qui est susceptible d'être installé dans un emplacement cohérent sur la plupart des systèmes ( /usr/bin/perlet /bin/bash, respectivement), j'utiliserais le chemin direct vers la commande. Pour quelque chose de plus obscur qui pourrait être installé différemment sur différents systèmes, j'utiliserais soit l' /usr/bin/envastuce, soit j'écrirais un programme d'installation qui ajuste la ligne shebang pendant l'installation du script. (J'avais l'habitude de le faire pour mes scripts Perl.)

MISE À JOUR: Je suis entré dans un peu plus de détails dans cette réponse à cette question sur le site Unix et Linux .

Keith Thompson
la source
Je viens de commencer à regarder Ruby, et j'ai trouvé que la convention dans Ruby est de commencer par [code] #! / Usr / bin / env ruby ​​[/ code] pour des raisons de portabilité. Certains ont noté que cela rend difficile la fourniture d'arguments de ligne de commande à l'interpréteur ruby, tels que «-w», ce qui serait également un problème pour Perl.
bgvaughan
@bgvaughan Pour Perl, il est traditionnel de nos jours d'utiliser #!/usr/bin/perlet d'utiliser use strict; use warnings;dans le corps du script plutôt que #!/usr/bin/perl -w. Mais -Tdoit être sur le shebang.
Keith Thompson
alors pourquoi ne pas utiliser #! perl si nous voulons juste le premier sur le chemin?
arrivé le
@wheredidthatnamecomefrom: Parce que cela ne fonctionne pas. Le traitement de la #!ligne n'utilise pas $PATH. Vous devez spécifier le chemin de l'interpréteur. (Je viens de réaliser que, au moins sur mon système, cela peut être un chemin relatif, mais c'est rarement utile.)
Keith Thompson
6

La meilleure pratique est la suivante:

#!/usr/bin/env bash 
#!/usr/bin/env sh
#!/usr/bin/env python

Etc...

Lorsque Ubuntu a commencé à utiliser Dash, certains scripts se sont cassés. Il y a eu une discussion à ce sujet. La plupart des scripts ont été écrits, #!/bin/shce qui était un lien vers / bin / bash. Le consensus est le suivant: le scénariste est chargé de spécifier l'interprète. Par conséquent, si votre script doit toujours être appelé avec BASH, spécifiez-le à partir de l'environnement. Cela vous évite d'avoir à deviner le chemin, qui est différent sur divers systèmes Unix / Linux. De plus, cela fonctionnera si demain / bin / sh devient un lien vers un autre shell comme / bin / wthsh ou une autre non-signification.


la source
La solution alternative évidente pour le problème de tiret était d'écrire #!/bin/bash. Je suis d'accord que le scénariste est responsable de spécifier l'interprète, mais tout cela signifie que si vous avez besoin de bash, dites bash not sh
Martin Bonner prend en charge Monica
1

Pour info c'est un bang #!, vous en avez besoin #. Vous utilisez cette ligne pour identifier l'interpréteur avec lequel exécuter le script.

Par défaut, Ubuntu établit un lien /bin/shvers le tableau de bord

Selon ce que vous aimeriez savoir sur le tableau de bord et pourquoi le tableau de bord est utilisé pour les shells système ou démons, voir:

cyberciti.biz dash

Page de manuel du tableau de bord Ubuntu

Bash est le shell par défaut utilisé par la plupart des utilisateurs de Linux, et possède différentes fonctionnalités puis dash. Un script écrit pour bash peut ou non s'exécuter correctement s'il est exécuté avec dash, plus le script est complexe, moins il s'exécutera.

Le script écrit pour perl, python, etc. ne fonctionnera pas du tout avec /bin/shou /bin/bash.

Donc, lorsque vous écrivez un script, vous identifiez quel interprète doit être utilisé avec le shee-bang

La sélection de ce qu'il faut utiliser est faite par l'auteur du script, et l'une n'est pas meilleure que l'autre, elles ont toutes diverses caractéristiques, avantages et inconvénients.

Panthère
la source