Všiml jsem si, že některé skripty, které jsem získal od jiných, mají shebang #!/path/to/NAME
zatímco ostatní (používající stejný nástroj, NAME) mají shebang #!/usr/bin/env NAME
.
Zdá se, že obojí funguje správně. V tutoriálech (například o Pythonu) se zdá, že se objevuje návrh, že druhý shebang je lepší. Ale úplně nechápu, proč tomu tak je.
Uvědomuji si, že aby bylo možné použít druhý shebang, NAME musí být v PATH, zatímco první shebang toto omezení nemá.
Také se mi zdá (mně), že první by byl lepší shebang, protože přesně určuje, kde se nachází JMÉNO. Pokud tedy v tomto případě existuje více verzí NAME (např. /usr/bin/NAME, /usr/local/bin/NAME), první případ určuje, která se má použít.
Moje otázka zní, proč je první shebang preferován před druhým?
Přijatá odpověď:
Objektivní kritéria/požadavky:
Při rozhodování, zda použít absolutní nebo logické (/usr/bin/env
) cestu k tlumočníkovi v bouři, existují (2) klíčové úvahy:
a) tlumočník lze nalézt v cílovém systému
b) Správná verze tlumočníka lze nalézt v cílovém systému
Pokud SOUHLASÍME že „b) ” je žádoucí,to také souhlasíme :
c) Je lepší, aby naše skripty selhaly namísto provádění pomocí nesprávné verze interpretu a potenciálně dosáhnout nekonzistentních výsledků.
Pokud NESOUHLASÍME že „b) ” záleží, pak bude stačit jakýkoli nalezený tlumočník.
Testování:
Od použití logického cesta- /usr/bin/env
k interpretu v she-bang je nejrozšířenějším řešením, které umožňuje úspěšné provedení stejného skriptu na cílových hostitelích s různými cestami ke stejnému interpretu, otestujeme jej – pomocí Pythonu kvůli jeho popularitě – abychom zjistili, zda splňuje naše kritéria.
- Zná
/usr/bin/env
žít na předvídatelném a konzistentním místě na OBLÍBENÉ (nikoli „každý ") Operační systémy? Ano :
- RHEL 7.5
- Ubuntu 18.04
- Raspbian 10 („Buster“)
- OSX 10.15.02
- Skript pod Python spouštěný uvnitř i vně virtuálních obálek (Pipenv použité) během testů:
#!/usr/bin/env pythonX.x import sys print(sys.version) print('Hello, world!')
- Ona ve skriptu byla přepnuta požadovaným číslem verze Pythonu (vše nainstalované na stejném hostiteli):
- #!/usr/bin/env python2
- #!/usr/bin/env python2.7
- #!/usr/bin/env python3
- #!/usr/bin/env python3.5
- #!/usr/bin/env python3.6
- #!/usr/bin/env python3.7
-
Očekávané výsledky:to
print(sys.version)
=env pythonX.x
. Pokaždé./test1.py
byla provedena pomocí jiné nainstalované verze Pythonu, byla vytištěna správná verze specifikovaná v she-bang. -
Poznámky k testování:
- Testy byly omezeny výhradně na Python
- Perl:Jako Python – MUSÍ žít v
/usr/bin
podle FHS - Nevyzkoušel jsem všechny možné kombinace na každém možném počtu operačních systémů Linuxy/Unixy a verzích jednotlivých operačních systémů.
Závěr:
I když je PRAVDA, že #!/usr/bin/env python
použije první verzi Pythonu, kterou najde v cestě uživatele, můžeme toto chování zmírnit zadáním čísla verze, například #!/usr/bin/env pythonX.x
. Vývojářům je ve skutečnosti jedno, který interpret bude nalezen „první “, záleží jim jen na tom, aby byl jejich kód spouštěn pomocí specifikovaného interpretu, o kterém vědí, že je kompatibilní s jejich kódem, aby zajistil konzistentní výsledky – kdekoli v souborovém systému …
Pokud jde o přenositelnost/flexibilitu, pomocí logického – /usr/bin/env
– spíše než absolutní cesta nejen splňuje požadavky a), b) a c) z mého testování s různými verzemi Pythonu , ale má také výhodu v tom, že fuzzy logika najde stejný interpret verzí, i když žijí na různých cestách na různých operačních systémech. A i když NEJVÍCE distribuce respektují FHS, ne všechny.
Kde tedy skript SELHNE pokud binární žije v různých absolutních cesta pak zadaná v shebang, stejný skript používající logický cesta ÚSPĚCHY jak pokračuje, dokud nenajde shodu, čímž nabízí větší spolehlivost a rozšiřitelnost napříč platformami.