gli script di shell funzionano ancora senza #! (linea sha-bang)


10

Sono nuovo agli script di shell e molti libri hanno scritto che usano la linea #! (Sha-bang) all'inizio dello script per invocare l'interprete. E questo invocherà una nuova shell per lo script e farà l'interpretazione riga per riga. della mia sceneggiatura di base è ancora in esecuzione senza la linea magica.

quindi le mie domande sono:

  • da dove il mio script di base ha ottenuto l'interprete.
  • come ha fatto lo script a localizzare l'interprete?

ora lascia che ti parli del mio script di base che contiene solo la seguente riga:

echo "sceneggiatura di base senza le linee magiche"


Risposte:


3

Se la linea magica non viene fornita, viene utilizzata una shell predefinita per eseguire lo script. Questa shell predefinita può essere Bourne shell (sh), come in alcuni casi, tuttavia, in alcuni altri tipi, la shell predefinita utilizzata è uguale alla shell di accesso per eseguirla. Il fatto è: non lasciare al sistema il compito di decidere la shell, fornire sempre la shell desiderata nella prima riga.


1
Sì ... forse la mia shell attuale sta invocando una shell predefinita per lo script shell che non ha numeri magici.
user1678213

1
@ user1678213 Sì, è la tua shell (e non il kernel) a farlo.
Gilles 'SO- smetti di essere malvagio' l'

1
Credo che POSIX imponga che / bin / sh sia usato in questo caso.
vonbrand,

2
@vonbrand Questo è un malinteso comune. POSIX non impone che la shell POSIX sia /bin/sh, solo per essere il primo sheseguibile trovato durante l'esplorazione di un PERCORSO conforme.
jlliagre,

3
Non è corretto, non è mai la "shell di accesso" utilizzata per eseguirla. Ciò che può accadere è che la shell chiamante (se lo script viene chiamato da una shell) può avere un figlio che la interpreta.
Stéphane Chazelas,

8

Quando si esegue un programma, il kernel verifica se inizia con una sequenza di byte magici . Se il file eseguibile inizia con #!, il kernel interpreta il resto della riga come un nome di interprete. Se il file eseguibile inizia con \177ELF(dove si \177trova il byte 127), carica il file come eseguibile ELF ; questo è il tipo normale sulla maggior parte dei sistemi unix al giorno d'oggi.

Se il kernel non riconosce il formato del file, rifiuta di eseguire il file e restituisce l'errore ENOEXEC (errore nel formato Exec). Quando la shell lo nota, si impegna a eseguire il programma come uno script di shell.

Per testimoniare questo in azione, aggiungi alcuni comandi al tuo script:

ps l $$
ls -l /proc/$$/exe
echo hello

(Questo è per Linux, regolare per altri unices.) Quindi provare a eseguire quello script da varie shell. Vedrai che alcune shell generano nuove istanze di se stesse per eseguire lo script (bash, ksh93) mentre altre spawn /bin/sh(trattino, pdksh, zsh).


Cosa cerco con il tuo ls -lcomando? Questo: lrwxrwxrwx 1 i 0 Oct 11 05:15 exe -> /bin/bash-? In tal caso, cosa dice? Inoltre, ho notato che ho SHELL=/bin/bashacceso env, ma cambiarlo non sembrava cambiare il comportamento. Forse non è correlato?
Emanuel Berg,

sembra che tu stia cambiando la variabile di shell "SHELL". se sì, allora stai solo modificando il valore della variabile di shell SHELL.it non cambierà la tua shell. per cambiare la tua shell modifica il file / etc / passwd.
user1678213,

2
@EmanuelBerg Sì (avrei dovuto scrivere ls -l /proc/$$/exe, in effetti). I execollegamenti indicano la shell che sta eseguendo il tuo script. Quando esegui lo script, vedrai che è bash che interpreta lo script. Se lo esegui ad es. Da pdksh, viene eseguito /bin/sh. Non conosco alcuna shell che utilizza la SHELLvariabile d'ambiente o la shell di login in quella circostanza.
Gilles 'SO- smetti di essere malvagio' l'

2
@ user1678213 La modifica della shell /etc/passwdcambia la shell eseguita quando si accede tramite SSH o su una console di testo. Non cambia quale shell potrebbe eseguire script.
Gilles 'SO- smetti di essere malvagio' l'

2
@ user1678213 Ho verificato ciò che ho scritto qui eseguendo dei test. Nessuna delle shell che ho testato ha esaminato /etc/passwdper decidere quale shell usare, o hanno biforcato un'istanza di se stessi o eseguita /bin/sh.
Gilles 'SO- smetti di essere malvagio' l'

-2

È probabilmente una delle seguenti 3 possibilità:

  1. Stai chiamando lo script direttamente con l'interprete, IE: bash script.sh

  2. Il nome del file di script ha un'estensione .sh, che consente al sistema di cercare il programma predefinito per questo tipo di file

  3. L'ambiente shell che stai utilizzando sta eseguendo 'echo' da solo, dal momento che posso solo immaginare che il file di script sia eseguibile. Se, ad esempio, stai usando una shell bash e hai un comando nel tuo file che è usato solo da ksh, allora vedrai che non funzionerà.

In bocca al lupo!


3
né l'ho chiamato con bash né con alcuna estensione.
user1678213

1
e l'ambiente shell non lo sta eseguendo perché quando invoco il comando ps dopo aver invocato il mio script. Il comando ps mostra due bash process.che significa che ci sono due bash in esecuzione. uno è il mio login bash shell e l'altro è bash per il mio basic_script
user1678213

1
2: il kernel non farà nulla del genere. Zsh può farlo, e bash può essere distorto nel farlo. 3: Sì, ma varia leggermente tra le shell, vedi la mia risposta.
Gilles 'SO- smetti di essere malvagio' l'
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.