Vraag Welk type pad in shebang heeft meer de voorkeur?


In scripts moet in de eerste regel het pad naar de tolk worden opgegeven.
Maar op verschillende servers Linux, Unix of BSD kan dit pad anders zijn.

Wat heeft meer de voorkeur?

#!/usr/bin/env bash 

of

#!/bin/bash 

15
2017-12-16 17:00


oorsprong




antwoorden:


Als u de door het systeem geïnstalleerde versie van een gegeven tolk wilt gebruiken die op een standaardlocatie is geïnstalleerd, gebruikt u het directe pad. Als je wilt gebruiken welke versie van de interpreter dan ook als eerste verschijnt in de gebruiker $PATH, gebruik #!/usr/bin/env ....

De env commando roept een gespecificeerde opdracht op, waarmee je omgevingsvariabelen kunt in- of uitschakelen:

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

Als u geen omgevingsvariabelen of andere opties opgeeft, roept deze alleen de opdracht named aan. (Het op deze manier gebruiken is waarschijnlijk een beetje een hack.)

Het doel van het schrijven van de shebang als

#!/usr/bin/env interp

is om wat dan ook aan te roepen interp verschijnt eerst in $PATH.

Dit betekent dat je bij het schrijven van het script niet precies hoeft te weten waar interp is (laten we zeggen, als het in een van beide kan zijn /bin, /usr/binof /usr/local/bin). Natuurlijk moet je dat weten env is /usr/bin/env, maar dat lijkt redelijk universeel te zijn.

Het voordeel is dat het de versie van de interpreter als eerste in de gebruiker oproept $PATH. De nadeel is dat het de versie van de interpreter als eerste in de gebruiker oproept $PATH.

Stel dat ik een persoonlijke build van heb geïnstalleerd perl onder mijn homedirectory, als $HOME/bin/perl, en ik heb $HOME/bin aan de voorkant van mijn $PATH. Als ik een script draai waarvan de shebang is

#!/usr/bin/env perl

dan zal het worden uitgevoerd met mijn eigen geïnstalleerd perl uitvoerbaar - wat misschien geen goede zaak is. De auteur van het script heeft het waarschijnlijk niet getest met de blead-edge Perl die ik een maand geleden uit bron heb gebouwd.

Voor iets als Perl of Bash dat waarschijnlijk op een consistente locatie op de meeste systemen wordt geïnstalleerd (/usr/bin/perl en /bin/bash,), zou ik het directe pad naar het commando gebruiken. Voor iets obscuurs dat op verschillende systemen anders zou kunnen worden geïnstalleerd, zou ik het /usr/bin/env trick, of ik zou een installatieprogramma schrijven dat de shebang-regel aanpast terwijl het script wordt geïnstalleerd. (Vroeger moest ik dat doen voor mijn Perl-scripts.)

BIJWERKEN : Ik ben in wat meer detail uitgegaan dit antwoord naar deze vraag op de Unix & Linux-site.


17
2017-12-16 20:55



Ik ben net op zoek gegaan naar Ruby en vond dat de conventie in Ruby is om te beginnen met [code] #! / Usr / bin / env ruby ​​[/ code] omwille van draagbaarheid. Sommigen merkten op dat dit het moeilijk maakt om commandoregelargumenten aan de robottolk te geven, zoals '-w', wat ook een probleem zou zijn voor Perl. - bgvaughan
@bgvaughan Voor Perl is het tegenwoordig gebruikelijk om te gebruiken #!/usr/bin/perl en gebruik dan use strict; use warnings; in het lichaam van het script, in plaats van #!/usr/bin/perl -w. Maar -T moet op de shebang zijn. - Keith Thompson
dus waarom zou u #! perl niet gebruiken als we alleen de eerste op het pad willen? - wheredidthatnamecomefrom
@wheredidthatnamecomefrom: Omdat dat niet werkt. De behandeling van de #! lijn gebruikt niet $PATH. U moet het pad van de tolk specificeren. (Ik realiseerde me net dat, althans op mijn systeem, het een relatief pad kan zijn, maar dat is zelden nuttig.) - Keith Thompson


De beste methode is dit:

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

Enzovoort...

Toen Ubuntu voor het eerst het dashboard begon te gebruiken, braken sommige scripts. Er was discussie over. De meeste scripts zijn geschreven #!/bin/sh welke een link was naar / bin / bash. De consensus is dit: de scriptschrijver is verantwoordelijk voor het opgeven van de tolk. Daarom, als uw script altijd moet worden aangeroepen met BASH, specificeer het dan vanuit de omgeving. Dit bespaart u het pad dat anders is op verschillende Unix / Linux-systemen. Bovendien zal het werken als morgen / bin / sh een link wordt naar een andere shell zoals / bin / wthsh of een andere nonsence.


6
2017-12-16 17:35



De voor de hand liggende alternatieve oplossing voor het probleem met het streepje was schrijven #!/bin/bash. Ik ben het ermee eens dat de scriptschrijver verantwoordelijk is voor het opgeven van de interpreter, maar dat betekent dat dat zo is als je bash nodig hebt, zeg dan bash not sh - Martin Bonner


Het is een schuiver #!, je hebt de #. U gebruikt deze regel om te identificeren met welke interpreter het script moet worden uitgevoerd.

Standaard koppelingen Ubuntu /bin/sh haasten

Afhankelijk van hoeveel u misschien wilt weten over dash en waarom dash wordt gebruikt voor systeem- of deamon-shells, zie:

cyberciti.biz dash

Ubuntu dash man-pagina

Bash is de standaard shell die door de meeste Linux-gebruikers wordt gebruikt en heeft verschillende functies dan dash. Een script dat is geschreven voor bash kan al dan niet correct worden uitgevoerd als het wordt uitgevoerd met een streepje, hoe complexer het script, hoe minder kans het loopt.

Script geschreven voor perl, python, etc. loopt helemaal niet mee /bin/sh of /bin/bash.

Dus wanneer u een script schrijft, identificeert u welke tolk moet worden gebruikt met de schaar

De keuze van wat te gebruiken is gemaakt door de auteur van het script, en de ene is niet beter dan de andere, ze hebben allemaal verschillende kenmerken, voordelen en nadelen.


1



Zie ook Waarom wijst / bin / sh naar / bin / dash en niet / bin / bash?. - enzotib