Perché devo inserire sh prima di eseguire i file .sh?


16

Quando voglio eseguire i .shfile in Terminal, devo metterli shdi fronte.

C'è un modo per evitarlo e quindi salvare la digitazione?


3
Ho creato una cartella in ~ / bin per inserire i miei script shell e inserirla nel mio $ PATH e ho anche allegato un'azione Cartella alla cartella ~ / bin per impostare automaticamente le autorizzazioni di esecuzione perché è così facile dimenticarlo.
Kaydell,

Risposte:


22

Se stai eseguendo il tuo script dalla shell, in realtà non hai bisogno dello #!/bin/shshebang come indicato in questa risposta - ogni sistema simile a Unix che ho usato, incluso OS X, sarà predefinito /bin/shse nessun interprete è specificamente specificato ( sebbene sia una buona idea poiché i non shell non sapranno come eseguire il tuo script se non dai lo shebang.)

Inoltre non hai bisogno di .shun'estensione. Si fa necessità di impostare le autorizzazioni eseguibili, ad esempio,

$ chmod +x script.sh

( $È il prompt della shell; lo sto usando per illustrare i comandi che dai alla shell interattiva. Non digitarlo!)

Tuttavia, penso che la tua confusione sia che hai creato uno script, ad esempio script.sh, nella directory corrente e stai provando a eseguirlo semplicemente digitando script.sh. per esempio

$ cat >script.sh
echo hello, world
^D
$ chmod +x script.sh
$ script.sh
-bash: script.sh: command not found

( ^Dsignifica control- D. Troverai questa notazione in molti articoli sull'uso di Unix.)

Il fatto che script.shin questo caso sia uno script di shell è solo metà del problema; il vero problema è che, per impostazione predefinita, la shell non cercherà un programma nella directory corrente. Tuttavia, questo funziona:

$ sh script.sh
hello, world

perché shsta prendendo la sceneggiatura come argomento.

È possibile eseguire uno script o, di nuovo, qualsiasi eseguibile, nella directory corrente, se è contrassegnato come eseguibile (ovvero chmod +x), specificando che si desidera eseguire quello nella directory corrente:

$ ./script.sh
hello, world

Puoi anche spostare lo script in una directory sul tuo PATH. Raccomando /usr/local/binper questo se lo script è destinato a essere utilizzato a livello di sistema o una bindirectory nella propria home se lo script è solo per te. Quest'ultimo richiede che tu aggiunga $HOME/bin, che si espande alla tua nuova directory bin, alla tua PATHaggiungendo le seguenti righe alla tua .profilenella tua home directory:

PATH=$HOME/bin:$PATH
export PATH

Infine, puoi, se vuoi, aggiungere effettivamente la directory corrente alla tua PATH, che ti permetterà di andare semplicemente in una directory contenente script.sh–o qualsiasi altro eseguibile – e digitare

$ script.sh

per eseguirlo. Tuttavia, non raccomando questa pratica , poiché un utente malintenzionato può ora indurti a eseguire un eseguibile arbitrario rilasciando uno script eseguibile (chiamato, diciamo, ls) in una directory in cui ti troverai. Se vuoi davvero farlo, però, aggiungi quanto segue al tuo .profile:

PATH=.:$PATH
export PATH

Metti il ​​'.' alla fine del $ PATH invece dell'inizio e ora non devi preoccuparti di un fantasma 'ls'. (Anche se qualcuno può entrare nel tuo sistema, hai problemi più grandi.)
TJ Luoma,

2
@TJ, ma non è necessario preoccuparsi di cose del genere slo di llso l... cioè, errori di battitura. Basta uscire .da $PATH. Inoltre, potresti non (o non dovresti) fidarti necessariamente di tutti sul tuo sistema. Ad esempio, supponiamo che ci sia qualche exploit che consente a un utente malintenzionato di rilasciare un file arbitrario in una directory, ma hanno bisogno che tu lo esegua per passare a un exploit migliore (ad esempio, raccogliere dati e telefonare a casa). Difesa in profondità!
Reid,

@TJLuoma Cosa ha detto @Reid, inoltre tieni presente che ci sono molti casi d'uso per un sistema Unix oltre a un desktop OS X personale. Non l'ho provato, ma scommetto che anche l'account guest potrebbe lasciare uno di questi elementi in /tmpun'altra directory scrivibile a livello mondiale.
zigg,

Se stai usando un sistema in cui altre persone hanno accesso alle directory che usi, hai problemi più grandi.
TJ Luoma,

@TJLuoma Faresti meglio a non usare mai più account su nessun sistema Unix. /tmpet al. vieni con il territorio.
zigg,

10

Non è necessario chiamare shse il file di script è contrassegnato come eseguibile. In tal caso, è possibile chiamarlo come si farebbe con qualsiasi altro comando dalla shell esistente.


Per essere del tutto corretto, ti consigliamo di fare due cose:

  1. Modifica il tuo script per includere una direttiva shebang nella parte superiore del tuo script:

    #!/bin/sh

    ... Questo direbbe alla shell quale interprete usare per eseguire lo script; in questo caso, l' /bin/sheseguibile.

  2. Contrassegna lo script come eseguibile da te con il comando chmod :

    chmod u+x scriptname.sh

Una volta eseguite entrambe, dovresti essere in grado di eseguire lo script digitando il nome del file dello script nella riga di comando. Dovrai trovarti nella stessa directory del tuo script, a meno che tu non faccia anche il passo aggiunto per aggiungere la cartella contenente alla tua variabile PATH . Se non ti interessa quale shell esegue lo script, non è necessario specificare il primo passaggio, shma spesso è meglio essere precisi e impostare "shebangsh".


Gli shebang non sono effettivamente necessari /bin/sh, anche se non fanno male.
zigg,

@zigg - Hai ragione. Spero che a Chris non dispiaccia le mie modifiche ... Nuke o ri-modifica come desiderato: -0
bmike

@bmike Le modifiche funzionano per me. Per quanto riguarda gli shebang, la mia abitudine era sempre quella di specificare perché ai kshmiei tempi scrivevo molti script su HP-UX, ma è bene sapere che non è strettamente necessario.
Chris W. Rea,

1
Penso di dover allontanarmi dalla mia precedente dichiarazione sulla necessità di shebang (anche se il resto della mia risposta è ancora valido). Puoi eseguire uno script senza shebang da una shell, ma se usi una execsyscall, ottieni ENOEXEC(errore formato exec ). Mi dispiace, @bmike, @ ChrisW.Rea. Ora vado a modificare la mia risposta.
zigg,
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.