GNU/Linux >> Linux Esercitazione >  >> Linux

Perché è meglio usare "#!/usr/bin/env Name" invece di "#!/path/to/name" come The Shebang?

Noto che alcuni script che ho acquisito da altri hanno lo shebang #!/path/to/NAME mentre altri (usando lo stesso strumento, NAME) hanno lo shebang #!/usr/bin/env NAME .

Entrambi sembrano funzionare correttamente. Nei tutorial (su Python, ad esempio), sembra esserci un suggerimento che quest'ultimo shebang sia migliore. Ma non capisco bene perché sia ​​così.

Mi rendo conto che, per poter utilizzare quest'ultimo shebang, NAME deve essere nel PERCORSO mentre il primo shebang non ha questa restrizione.

Inoltre, sembra (a me) che il primo sarebbe il migliore shebang, poiché specifica esattamente dove si trova NAME. Quindi, in questo caso, se esistono più versioni di NAME (ad es. /usr/bin/NAME, /usr/local/bin/NAME), il primo caso specifica quale utilizzare.

La mia domanda è perché il primo shebang è preferito al secondo?

Risposta accettata:

Criteri/Requisiti obiettivi:

Nel determinare se utilizzare un assoluto o logico (/usr/bin/env ) percorso verso un interprete in un she-bang, ci sono (2) considerazioni chiave:

a) L'interprete può essere trovato sul sistema di destinazione

b) La versione corretta di interprete può essere trovato sul sistema di destinazione

Se ACCORDIAMO che "b) ” è auspicabile, siamo anche d'accordo che :

c) È preferibile che i nostri script falliscano piuttosto che eseguire utilizzando una versione errata dell'interprete e ottenere risultati potenzialmente incoerenti.

Se NON ACCORDIAMO che "b) ” importa, allora qualsiasi interprete trovato sarà sufficiente.

Test:

Da quando si utilizza una logica percorso- /usr/bin/env per l'interprete in she-bang è la soluzione più estensibile che consente allo stesso script di essere eseguito con successo su host di destinazione con percorsi diversi verso lo stesso interprete, lo testeremo - usando Python a causa della sua popolarità - per vedere se soddisfa i nostri criteri.

  1. Fa /usr/bin/env vivere in una posizione prevedibile e coerente su POPULAR (non "tutti ") Sistemi operativi? :
  • RHEL 7.5
  • Ubuntu 18.04
  • Raspbian 10 ("Buster")
  • OSX 15.10.02
  1. Sotto script Python eseguito sia all'interno che all'esterno degli inviluppi virtuali (Pipenv utilizzato) durante i test:
    #!/usr/bin/env pythonX.x
    import sys
    print(sys.version)
    print('Hello, world!')
    
  2. Il botto nello script è stato attivato dal numero di versione di Python desiderato (tutti installati sullo stesso host):
  • #!/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
  1. Risultati attesi:quel print(sys.version) =env pythonX.x . Ogni volta ./test1.py è stato eseguito utilizzando una versione di Python installata diversa, è stata stampata la versione corretta specificata in she-bang.

  2. Note di prova:

  • I test erano limitati esclusivamente a Python
  • Perl:come Python- DEVE vivere in /usr/bin secondo l'FHS
  • Non ho provato tutte le combinazioni possibili su ogni numero possibile di sistema operativo Linuxy/Unixy e versione di ciascun sistema operativo.
Correlati:Linux – Ottenere le capacità dell'unità CD/DVD quando wodim –devices non funziona?

Conclusione:

Anche se è VERO che #!/usr/bin/env python utilizzerà la prima versione di Python che trova nel percorso dell'utente, possiamo moderare questo comportamento specificando un numero di versione come #!/usr/bin/env pythonX.x . In effetti, agli sviluppatori non interessa quale interprete viene trovato "prima ", tutto ciò a cui tengono è che il loro codice venga eseguito utilizzando l'interprete specificato che sanno essere compatibile con il loro codice per garantire risultati coerenti- ovunque possa risiedere nel filesystem

In termini di portabilità/flessibilità, utilizzando una logica /usr/bin/env – piuttosto che assoluto il percorso non solo soddisfa i requisiti a), b) e c) dei miei test con diverse versioni di Python , ma ha anche il vantaggio della logica fuzzy che trova lo stesso interprete di versione anche se vive in percorsi diversi su sistemi operativi diversi. E sebbene LA MAGGIOR PARTE le distribuzioni rispettano l'FHS, non tutte lo fanno.

Quindi, dove uno script FALLITO se il binario vive in assoluto diverso percorso quindi specificato in shebang, lo stesso script utilizzando un logico percorso SUCCESSO mentre continua fino a quando non trova una corrispondenza, offrendo così maggiore affidabilità ed estensibilità su tutte le piattaforme.


Linux
  1. /usr/bin Vs /usr/local/bin Su Linux?

  2. Perché /bin/sh punta a /bin/dash e non a /bin/bash??

  3. Quando dovrei usare /dev/shm/ e quando dovrei usare /tmp/?

  4. Perché mettere cose diverse da /home in una partizione separata?

  5. Differenza tra /bin e /usr/bin

cmake --version punta a /usr/bin/cmake mentre which cmake punta a /usr/local/bin

Qual è il significato di /usr/sbin, /usr/local/sbin e /usr/local/bin?

Quando devo usare #!/bin/bash e quando #!/bin/sh?

Perché su alcuni sistemi Linux, il filesystem di root appare come /dev/root invece di /dev/<real device node>in mtab?

Perché le directory /home, /usr, /var, ecc. hanno tutte lo stesso numero di inode (2)?

Perché sono necessari < o > per usare /dev/tcp