Qual è la differenza tra ./ e sh per eseguire uno script?

63

Ho scritto un semplice script. Quando eseguo sh <myscriptname.sh> , ho ottenuto l'output corretto, ma quando eseguo ./<myscriptname.sh> , ho ricevuto un errore.

Qual è la differenza tra quando faccio sh e ./ ?

    
posta mr_eclair 23.01.2011 - 16:16

6 risposte

61

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 apparirebbe come il processo 'sh' con l'argomento 'nomefile.sh'. L'interprete sh sta aprendo il file.

D'altra parte se si esegue lo script stesso, il sistema richiama il programma interprete specificato e alimenta il contenuto degli script. In questo caso il processo appare come 'filename.sh' senza argomenti.

Assicurati di avere una linea di demarcazione:

#!/bin/bash
# bash script here

Una linea di botto è la prima riga nello script e inizia con gli stessi due caratteri #! , questi sono i messaggi letti dal sistema quando tenta di eseguire lo script e quindi il sistema passa lo script per il programma subito dopo. Nota che questa linea non ha nulla a che fare con bash e funziona altrettanto bene per python e perl, anche se sono lingue molto diverse. Ad esempio, dovresti usare #!/usr/bin/python e poi seguirlo con codice python.

Una volta che hai lo script, assicurati di aver impostato le autorizzazioni di esecuzione:

chmod a+x filename.sh

Quindi puoi eseguire lo script come processo proprio:

./filename.sh

Oppure metti il ​​file in una posizione nota con un nome di programma piacevole, ad esempio /usr/sbin ed esegui ovunque:

sudo cp filename.sh /usr/sbin/program-name
program-name

E questo è davvero il pratico beneficio dell'uso della linea bang con le giuste autorizzazioni - si tratta di implementazione . È molto difficile convincere gli utenti a eseguire uno script se devono ricordare con quale programma eseguire lo script. Ricorda di dare un percorso completo alla sceneggiatura ogni volta che vogliono eseguirlo. Dove, ad esempio, metterlo in /usr/local/bin e renderlo eseguibile, può salvare un sacco di dolore per le persone che cercano di usare il tuo script. Questi programmi diventano quindi disponibili per tutti utenti sul tuo computer.

È anche un bene per l'identificazione. Se vai nel programma top , uno script eseguito senza la linea di botto avrà solo il nome dell'interprete, cioè bash , perl o python . Ma se uno script viene eseguito con le autorizzazioni corrette, viene visualizzato il nome dello script.

Nota: se vuoi distribuire uno script accessibile a tutti, ti preghiamo di creare una pagina man e un pacchetto deb per installarlo. Dobbiamo ridurre il numero di script casuali online e aumentare il numero di deb che è possibile disinstallare.

    
risposta data Martin Owens -doctormo- 23.01.2011 - 16:31
35

La versione breve:

  • sh è l'interprete della riga di comando (trattino).
    L'esecuzione di sh my_script rende dash interpretare lo script.

  • ./ cerca di scoprire quale interprete usare, guardando la prima riga. Per esempio. #!/bin/bash , o anche #!/bin/ruby (come opsetto per eseguire ruby my_script ).

risposta data Stefano Palazzo 23.01.2011 - 16:44
3

La differenza che fai è

  • con sh , stai eseguendo un programma che interpreterà le righe nel tuo script così come lo avresti digitato sul prompt interattivo del terminale,

  • con ./ stai facendo una scorciatoia assumendo 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 ), salvando tempo inestimabile per i tempi futuri: -)

risposta data meduz 23.01.2011 - 23:13
3

Ci sono tre motivi principali per cui potresti ricevere un errore:

  • il file non è eseguibile
    esegui chmod +x <myscriptname.sh> per risolvere il problema
  • la partizione non consente gli script in esecuzione (è montato " noexec ")
    copia lo script in /usr/local/bin
  • la riga #! ha un errore
    assicurati che la prima riga sia #!/bin/sh o #!/bin/bash

Se la tua prima linea sembra giusta, ma ancora non funziona, assicurati che il file non abbia terminazioni di linea DOS.

L'errore sarebbe simile a questo:

$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory

Puoi correggerlo eseguendo dos2unix <myscriptname.sh> , o se non lo hai,
perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh> .

    
risposta data Mikel 03.02.2011 - 23:03
0

E la risposta è che sh è il nome per shell molto popolare. Ma obsoleto e sostituito da altri. Oggi sh è collegato ad altre shell installate sulla macchina. per esempio. Ho fatto irruzione lì. L'esecuzione di qualsiasi shell da sh in genere attiva la modalità 'compatibilità' con il comportamento 'shell' originale.

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 potrebbero esserci alcuni errori nello script stesso. Come dipendenza che viene soddisfatta da sh, ma non da interprete effettivamente utilizzata.

    
risposta data przemo_li 23.01.2011 - 18:09
0
mkdir ~/bin ; cp myscript.sh ~/bin/

echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ; 

Non /usr/sbin , ovvero per strumenti amministrativi non essenziali, /usr/local/bin è una scelta migliore se non vuoi avere un ~/bin/ , ma evita sudo per quanto possibile è consigliabile.

    
risposta data Joey1978 24.01.2011 - 08:25

Leggi altre domande sui tag