Chiamare uno script con ./bla.sh vs.. bla.sh


11

Qualcuno può spiegarmi cosa fa la shell nei due esempi A) e B) di seguito? Ovviamente si comporta diversamente, ma non riesco a capire perché l'output sia diverso.

Esempio:
disponiamo di uno script nella nostra directory corrente denominato bla.shcon un solo comando:
echo ${0##/*} hello

A)
Iniziato come: ./bla.sh
dà:./bla.sh hello

B)
Iniziato come: . bla.sh
dà:-bash hello

Dato che lo uso in uno script, il secondo output (a causa del "-" davanti al -bash) uccide il comando. Certo, un semplice aiuto --prima ${...}, ma mi piacerebbe capire in primo luogo ciò che provoca l'output.
Adoro bash. E vi [m]. Ma sto divagando ...

Risposte:


22
./bla.sh

Qui, il comando è ./bla.sh. Questo fa sì che la shell cerchi un eseguibile chiamato bla.shnella directory corrente, quindi chiede al kernel di eseguirlo come un normale programma, in un processo separato dalla shell. (Non importa se si bla.shtratta di uno bashscript, uno perlo pythonuno o un file binario compilato.)


. bla.sh

Qui, il comando è .(aka source), un comando integrato della tua shell. Fa in modo che la shell cerchi un file chiamato bla.shnel percorso di sistema ($ PATH) e interpreta i contenuti come se fossero stati digitati da te; tutto ciò avviene nello stesso processo della shell stessa (e quindi può influire sullo stato interno della shell).

Questo ovviamente funziona solo quando bla.shcontiene comandi per la bashshell (se è quello attualmente in uso), non funzionerà per gli perlscript o altro.

(Questo è spiegato in help .e help sourceanche.)


Dato .che ./sono cose completamente diverse (un comando rispetto a una parte di un percorso), ovviamente possono essere combinate - usando . ./bla.sh"rintracciare" un file bla.shnella directory corrente.


Di solito è meglio usare il ./bla.shmetodo. Solo ~/.bashrc, ~/.profilee tali file sono generalmente di provenienza, perché dovrebbero modificare l'ambiente corrente.


3
Inoltre, se cambi ambiente bash in bla.sh, queste modifiche vengono prese in considerazione dopo. bla.sh ma non dopo ./bla.sh. questo è perché . bla.sh viene eseguito nel contesto dell'attuale bash mentre ./bla.sh viene eseguito come sottoprocesso.
mouviciel,

1
Vedi anche mywiki.wooledge.org/BashFAQ/060 per alcuni esempi. Nota che sourceè un alias bash ., non il contrario e sourcenon funzionerà in altre shell.
mrucci,

7

./<cmd>eseguirà il <cmd>programma che risiede nella directory corrente in un nuovo processo (biforcato). Deve essere eseguibile. E anche leggibile inizia con #!.

. <cmd>farà eseguire alla shell corrente lo script della shell <cmd>che risiede nella $PATHdirectory corrente o dell'utente nel processo della shell corrente . Deve essere leggibile. È un alias per il comando shell source.


-1 . <cmd>cercherà il programma in $PATHe se non lo trova POI cercherà nella directory corrente.
dogbane,

@dogbane Bene, ho corretto questo.
kmkaplan,

FWIW, non tutte le shell cercheranno script di provenienza in cwd. zsh (almeno con la configurazione che ho) richiede. ./cmd
bstpierre il

1
@bstpierre Questo sembra essere un terreno in movimento. Il riferimento POSIX che ho dice che "la shell deve usare il percorso di ricerca specificato da PATH" e "Alcune implementazioni precedenti hanno cercato il file nella directory corrente, anche se il valore di PATH non lo ha consentito."
kmkaplan,

1

./cmd usa il percorso esplicito ( ./- dir corrente) all'eseguibile. E non è necessario che inizi con #!.

. cmd- (aka source) - comando incorporato bash. Una differenza visibile nell'esecuzione sourceè che può impostare / modificare la variabile di ambiente della shell corrente.


più precisamente, sourceè un alias solo bash di .(che è standard)
user1686

Hai ragione. Fisso.
Leonid Volnitsky,
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.