Qual è la differenza tra lesecuzione di “ bash script.sh ” e “ ./script .sh ”?

Se script.sh è solo qualcosa di tipico come

#!/bin/bash echo "Hello World!" 

Cè un preferito modo di eseguire lo script? Penso che devi prima modificarlo in modo che diventi eseguibile?

Risposta

Per il tuo script specifico funzionerà in entrambi i modi, tranne che ./script.sh richiede lesecuzione e bit leggibili, mentre bash script.sh richiede solo bit leggibile.


Il motivo di la differenza dei requisiti di autorizzazione sta nel modo in cui viene caricato il programma che interpreta lo script:

  • ./script.sh fa in modo che la shell esegua il file come se fosse un normale eseguibile.

La shell si biforca e utilizza una chiamata di sistema (ad esempio execve) per fare in modo che il sistema operativo esegua il file nel processo biforcuto. Il sistema operativo controllerà i permessi del file (quindi il bit di esecuzione deve essere impostato) e inoltrerà la richiesta al programma di caricamento , che guarda il file e determina come eseguirlo. In Linux gli eseguibili compilati iniziano con un numero magico ELF , mentre gli script iniziano con un #! ( hashbang ). Unintestazione hashbang significa che il file è uno script e deve essere interpretato dal programma specificato dopo lhashbang. Ciò consente uno script stesso per dire al sistema come interpretare lo script.

Con il tuo script, il caricatore del programma eseguirà /bin/bash e passerà ./script.sh come argomento della riga di comando.

  • bash script.sh fa eseguire la shell bash e passa script.sh come argomento della riga di comando

Quindi il sistema operativo caricherà (senza nemmeno guardare script.sh, perché è solo un argomento della riga di comando). Il processo bash creato interpreterà quindi script.sh perché viene passato come argomento della riga di comando. Perché script.sh viene letto solo da bash come file normale, il bit di esecuzione non è richiesto.


Consiglio di utilizzare ./script.sh però, perché potresti non sapere quale interprete richiede lo script. Quindi lascia che sia il programma di caricamento a determinarlo per te.

Commenti

  • Se il bit eseguibile non è impostato, puoi anche eseguire lo script eseguendo ". ./script.sh"
  • @Dog Hai ragione. Il punto è una scorciatoia per il comando integrato ' source ' , che esegue lo script nel processo bash corrente. Quindi è richiesto solo il bit leggibile.
  • @Dogeatcatworld mentre ciò è vero, lesecuzione di . ./script.sh non è la stessa cosa come (o ./script.sh. Considera lo script #!/usr/bin/python -V < newline > print test.
  • Attenzione che lacquisizione di uno script potrebbe causare la contaminazione della sessione interattiva. Ad esempio, se uno script modifica la variabile di ambiente PATH, questa modifica influirà sui comandi eseguiti dopo lorigine. Questo approccio dovrebbe davvero essere riservato alle situazioni in cui si dipende dagli effetti collaterali (script di configurazione dellambiente e simili). Per altre situazioni in cui è possibile ' t modificare le autorizzazioni, eseguire il comando nella riga Shebang, seguito dal nome dello script è lapproccio più sicuro.
  • Nota che , se provi uno script nella directory corrente, non è necessario utilizzare ./ ; dì solo . script.sh. Ma sono daccordo con le persone che scoraggiano luso del comando . su script che non dovevano essere invocati in questo modo. Sono sorpreso che nessuno abbia menzionato il fatto che, se lo script contiene comandi exit e tu lo provi, potrebbe disconnetterti. Un problema meno grave sarebbe se lo script eseguisse un cd, poiché ciò influenzerebbe anche la shell principale (interattiva).

Answer

bash script.sh richiama lo script direttamente utilizzando la bash.
./script.sh sta usando lo shebang #!/bin/bash per determinare come eseguire.

Se vuoi davvero sapere, quale binario viene eseguito se fai un bash script.sh potresti scoprirlo con which bash.

Quindi nel tuo esempio non fa differenza. Sì, devi chmod +x script.sh per poterlo eseguire direttamente tramite ./script.sh.

Commenti

  • Beh, non fa differenza supporre che /bin/bash sia il primo bash nel tuo $PATH.
  • ' hai ragione. E lo shebang #!/bin/bash funziona solo se è presente un /bin/bash
  • Bash (versione 4.2.37) sul mio il sistema esegue gli script anche senza il bit di esecuzione impostato. Perché dici che il bit di esecuzione è richiesto?
  • Sì, il bit di esecuzione è necessario solo invocando tramite ./script.sh.

Risposta

Crea un file Delete_Self.sh in questo modo:

 #!/bin/rm echo I am still here! 

Esegui questo come sh Delete_Self.sh vedrai “Sono ancora qui!” echo di nuovo.

Rendilo eseguibile ed eseguilo come ./Delete_Self.sh vedrai che non viene restituito nulla, mentre il file Delete_Self.sh stesso è andato.

Quindi la differenza è che:

  • bash script.sh ignorerà il #! riga, perché bash è specificato come programma per eseguire script.sh.
  • ./script.sh leggerà il #! riga per determinare il programma da eseguire script.sh.

Commenti

  • +1 per il bellesempio

Risposta

Oltre alle altre risposte, conoscere la differenza tra lesecuzione di uno script tramite ./script.sh (i) e source ./script.sh (ii) è utile – La versione (i) crea una nuova shell in cui eseguire il comando, mentre (ii) lo esegue nella shell corrente, il che può essere obbligatorio se leseguibile cambia le variabili dambiente che devono essere preservate dopo luscita delleseguibile. Ad esempio, per attivare un ambiente conda python è necessario utilizzare quanto segue:

source activate my_env 

N.B. Unaltra alternativa a source che potresti incontrare è il . integrato, ovvero

. activate my_env 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *