Quale tipo di percorso in shebang è più preferibile?


20

Negli script, la prima riga deve specificare il percorso dell'interprete.
Ma su diversi server Linux, Unix o BSD questo percorso potrebbe essere diverso.

Cosa è più preferibile?

#!/usr/bin/env bash 

o

#!/bin/bash 

Risposte:


22

Se si desidera utilizzare la versione installata dal sistema di un determinato interprete installato in una posizione standard, utilizzare il percorso diretto. Se si desidera utilizzare qualsiasi versione dell'interprete appaia per prima nell'utente $PATH, utilizzare #!/usr/bin/env ....

Il envcomando richiama un comando specificato, che consente di impostare o annullare l'impostazione delle variabili di ambiente:

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

Se non specifichi alcuna variabile d'ambiente o altre opzioni, invocherà semplicemente il comando denominato. (Usarlo in questo modo è probabilmente un po 'un trucco.)

Lo scopo di scrivere lo shebang come

#!/usr/bin/env interp

è invocare ciò che interpappare per primo in $PATH.

Questo significa che non c'è bisogno di sapere, quando si scrive la sceneggiatura, esattamente dove interpè (per esempio, se potesse essere in entrambi /bin, /usr/bino /usr/local/bin). Ovviamente devi sapere che lo envè /usr/bin/env, ma sembra essere ragionevolmente universale.

Il vantaggio è che richiama la versione dell'interprete che appare per prima nell'utente $PATH. Lo svantaggio è che richiama la versione dell'interprete che appare per prima nell'utente $PATH.

Ad esempio, supponiamo di aver installato una build personale perlnella mia home directory, come $HOME/bin/perl, e che ho $HOME/binnella parte anteriore della mia $PATH. Se eseguo una sceneggiatura di cui è shebang

#!/usr/bin/env perl

quindi verrà eseguito con il mio perleseguibile installato , il che potrebbe non essere una buona cosa. L'autore della sceneggiatura probabilmente non lo ha testato con il Perl all'avanguardia che ho costruito dalla fonte un mese fa.

Per qualcosa come Perl o Bash che probabilmente verrà installato in una posizione coerente sulla maggior parte dei sistemi ( /usr/bin/perle /bin/bash, rispettivamente), userò il percorso diretto al comando. Per qualcosa di più oscuro che potrebbe essere installato in modo diverso su sistemi diversi, utilizzerei il /usr/bin/envtrucco o scrivo un programma di installazione che regola la riga di shebang mentre lo script viene installato. (Prima dovevo farlo per i miei script Perl.)

AGGIORNAMENTO: Ho approfondito un po 'di più in questa risposta a questa domanda sul sito Unix e Linux .


Ho appena iniziato a cercare Ruby e ho scoperto che la convenzione in Ruby è di iniziare con [code] #! / Usr / bin / env ruby ​​[/ code] per motivi di portabilità. Alcuni hanno notato che ciò rende difficile fornire argomenti della riga di comando all'interprete ruby, come '-w', che sarebbe anche un problema per Perl.
bgvaughan,

@bgvaughan Per Perl, al giorno d'oggi è tradizionale solo usare #!/usr/bin/perle poi usare use strict; use warnings;nel corpo dello script, piuttosto che #!/usr/bin/perl -w. Ma -Tdeve essere sullo shebang.
Keith Thompson,

quindi perché non usare #! perl se vogliamo solo il primo sul percorso?
wheredidthatnamecomeda

@wheredidthatnamecomefrom: Perché non funziona. Il trattamento della #!linea non utilizza $PATH. Devi specificare il percorso dell'interprete. (Mi sono appena reso conto che, almeno sul mio sistema, può essere un percorso relativo, ma raramente utile.)
Keith Thompson,

6

La migliore pratica è questa:

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

E così via...

Quando Ubuntu ha iniziato a usare dash, alcuni script si sono rotti. Si è discusso al riguardo. La maggior parte degli script sono stati scritti #!/bin/shche era un collegamento a / bin / bash. Il consenso è questo: lo sceneggiatore è responsabile della specifica dell'interprete. Pertanto, se lo script deve essere sempre invocato con BASH, specificarlo dall'ambiente. Questo ti evita di dover indovinare il percorso, che è diverso su vari sistemi Unix / Linux. Inoltre, funzionerà se domani / bin / sh diventerà un collegamento ad altre shell come / bin / wthsh o qualche altra assurdità.


L'ovvia soluzione alternativa per il problema trattino era scrivere #!/bin/bash. Sono d'accordo che lo sceneggiatore è responsabile della specifica dell'interprete, ma tutto ciò che significa è se hai bisogno di bash, dì bash non sh
Martin Bonner supporta Monica

1

Cordiali saluti, è uno sballo #!, hai bisogno di #. Utilizzare questa riga per identificare con quale interprete eseguire lo script.

Di default, Ubuntu si collega /bin/sha dash

A seconda di quanto potresti voler sapere su dash e perché dash è usato per shell di sistema o di Deamon, vedi:

trattino cyberciti.biz

Pagina man di dash di Ubuntu

Bash è la shell predefinita utilizzata dalla maggior parte degli utenti Linux e presenta diverse funzionalità rispetto a dash. Uno script scritto per bash può o non può essere eseguito correttamente se eseguito con trattino, più complesso è lo script, meno probabile sarà l'esecuzione.

Lo script scritto per perl, python, ecc. Non funzionerà affatto /bin/sh o /bin/bash.

Quindi, quando scrivi una sceneggiatura, identifichi quale interprete dovrebbe essere usato con lo shee bang

La scelta di cosa usare è fatta dall'autore dello script, e uno non è migliore di un altro, hanno tutti varie caratteristiche, vantaggi e svantaggi.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.