Ho scritto una sceneggiatura semplice. Quando corro sh <myscriptname.sh>
, ho ottenuto l'output corretto, ma quando corro ./<myscriptname.sh>
, ho ricevuto un errore.
Qual è la differenza tra quando lo faccio sh
e ./
?
Ho scritto una sceneggiatura semplice. Quando corro sh <myscriptname.sh>
, ho ottenuto l'output corretto, ma quando corro ./<myscriptname.sh>
, ho ricevuto un errore.
Qual è la differenza tra quando lo faccio sh
e ./
?
Risposte:
Quando si esegue uno script passando il nome file al programma interprete di script, si esegue il programma interprete con lo script come argomento passato in esso. Ad esempio, questo assomiglierebbe al processo 'sh' con l'argomento 'nomefile.sh'. L' sh
interprete sta aprendo il file.
D'altra parte, se si esegue lo script stesso, il sistema chiama il programma interprete specificato e inserisce i contenuti degli script. In questo caso il processo appare come 'nomefile.sh' senza argomenti.
Dovresti assicurarti di avere una linea di bang:
#!/bin/bash
# bash script here
Una bang line è la prima riga dello script e inizia con gli stessi due caratteri #!
, questi sono ciò che il sistema legge quando tenta di eseguire lo script e quindi il sistema passa lo script al programma immediatamente dopo. Nota che questa linea non ha nulla a che fare con bash e funziona altrettanto bene per python e perl, anche se sono linguaggi molto diversi. Dovresti usare #!/usr/bin/python
ad esempio e poi seguirlo con il codice Python.
Una volta che hai il tuo script, assicurati di aver impostato le autorizzazioni di esecuzione:
chmod a+x filename.sh
Quindi è possibile eseguire lo script come processo proprio:
./filename.sh
O metti il file in un percorso noto con un bel nome di programma, come /usr/sbin
ed eseguilo da qualsiasi luogo:
sudo cp filename.sh /usr/sbin/program-name
program-name
E questo è davvero il vantaggio pratico dell'uso della bang line con le giuste autorizzazioni: si tratta solo di implementare . È molto difficile indurre gli utenti a eseguire uno script se devono ricordare con quale programma eseguire lo script. Ricorda di dare un percorso completo allo script ogni volta che vogliono eseguirlo. Dove, /usr/local/bin
ad esempio, inserendolo e rendendolo eseguibile, puoi risparmiare un sacco di dolore per le persone che cercano di usare la tua sceneggiatura. Questi programmi diventano quindi disponibili per tutti gli utenti sul tuo computer.
È anche buono per l'identificazione. Se entri nel top
programma, uno script eseguito senza la linea di bang avrà solo il nome dell'interprete bash
, ovvero , perl
o python
. Ma se uno script viene eseguito con le autorizzazioni giuste, viene visualizzato il nome dello script.
Nota: se si desidera distribuire uno script accessibile a tutti, creare una pagina man e un pacchetto deb per installarlo. Dobbiamo ridurre il numero di script casuali online e aumentare il numero di debs che possono essere disinstallati.
bash
no sh
.
PATH
.
/usr/local/bin
è probabilmente meglio allora /usr/sbin
- indica che il programma è locale a questa macchina piuttosto che essere parte della distribuzione.
La versione corta:
sh
è l'interprete della riga di comando (trattino).
L'esecuzione sh my_script
consente a dash di interpretare lo script.
./
cerca di scoprire quale interprete usare, guardando la prima riga. Ad esempio #!/bin/bash
, o addirittura #!/bin/ruby
(al contrario di correre ruby my_script
).
./
trova nulla, è il metodo di esecuzione del sistema che esamina i primi due byte del file.
sh
e il file contiene uno sha-bang, significa che lo sha-bang verrà ignorato o aprirà la shell dove sh
anche i collegamenti e quindi forse qualche altra shell o cosa fa :)?
La differenza che fai è
con sh
, stai eseguendo un programma che interpreterà le linee nel tuo script proprio come le avresti digitate sul prompt interattivo del terminale,
con ./
cui stai facendo una scorciatoia supponendo che lo script sia proprio qui nella directory corrente in cui ti trovi E sarà eseguibile (perché per esempio hai emesso chmod +x myscript.sh
), risparmiando tempo prezioso per tempi futuri :-)
sh
il file non deve essere necessariamente eseguibile.
Esistono tre motivi principali per cui potresti ricevere un errore:
chmod +x <myscriptname.sh>
per risolvere questonoexec
") su cui /usr/local/bin
#!
riga presenta un errore #!/bin/sh
o#!/bin/bash
Se la tua prima riga sembra corretta, ma continua a non funzionare, assicurati che il file non abbia terminazioni di riga DOS.
L'errore sarebbe simile al seguente:
$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory
È possibile risolvere il problema eseguendo dos2unix <myscriptname.sh>
, o se non si dispone di questo,
perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>
.
E la risposta è che sh è il nome di una shell molto popolare. Ma obsoleto e sostituito da altri. Oggi sh è collegato ad altre shell installate sulla macchina. ad esempio ho messo la bash lì. L'esecuzione di qualsiasi shell da sh in genere attiva una modalità di "compatibilità" con comportamento originale "shell".
Quindi la soluzione è abbastanza semplice. Guarda cosa c'è dietro il comando sh (ls -al / bin / sh) e metti #! / Bin / whatever_you_find_there come prima riga (o se c'è qualcosa di simile nel tuo script modificalo).
E in alternativa potrebbe esserci qualche bug nello script stesso. Come la dipendenza che incontra sh, ma non l'interprete effettivamente utilizzato.
mkdir ~/bin ; cp myscript.sh ~/bin/
echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ;
No /usr/sbin
, è per gli strumenti amministrativi non essenziali, /usr/local/bin
è una scelta migliore se non si desidera avere un ~/bin/
, ma sudo
è consigliabile evitare il più possibile.
~/.profile
ha già il codice per l'aggiunta ~/bin
, se esiste, a PATH
. In un'altra nota, non inserire estensioni negli script.
ls ~/bin/|wc -l = 428
) Ho messo un sacco di roba lì dentro;)
/bin
e /usr/bin
vedrai che non usano le estensioni.