.sh specificando l'estensione?


12

Perché alcuni sistemi eseguiranno un .shfile semplicemente specificando il nome del file senza estensione e altri richiedono il nome più l'estensione? Nel mio caso sto cercando di scrivere una serie di comandi seguendo queste istruzioni .

Sto specificando l'estensione ora, ma .shsarebbe preferibile poter eseguire i comandi senza .


4
L'uso .shcome estensione è in molte circostanze considerato una cattiva pratica: è contrario al modo in cui vengono denominati altri comandi (non si esegue ls.elf), spesso è fuorviante (se si foo.shinizia con #!/bin/bash, quindi l'esecuzione sh foo.shlo eseguirà con un interprete diverso da quello per cui è stato creato ) e se riscrivi foo.shper essere un programma Python, l'utilizzo di tale estensione significa che devi scegliere tra mantenere il nome ora fuorviante e riscrivere ogni programma che lo chiama.
Charles Duffy,

2
... dove è una buona pratica sono le librerie di shell, non i comandi con +xset - dove foo.shc'è una libreria che può essere fornita in qualsiasi shell POSIX, foo.bashpuò essere fornita in bash, foo.kshin ksh, ecc.
Charles Duffy,

Risposte:


39

Sei confuso. L' .shestensione è solo un suggerimento per gli umani e non ha assolutamente alcun effetto su come il sistema gestisce il file. Unix / Linux non ha fatto l' Secrets.pdf.exeerrore di Windows .

Ecco cosa succede quando si digita foo:

  1. Reindirizzamento per STDIN, STDOUTe STDERRsono istituiti.

  2. La shell controlla la sua tabella hash interna per vedere se conosce già una $PATHvoce per foo. Se non esiste nessuno, la shell cerca nelle directory $PATH, cercando un file chiamato foocon il bit Execute impostato nelle autorizzazioni per i file. Prima foovince.

  3. Se i primi due byte del file foosono #!, la stringa successiva è il nome di un interprete da eseguire. Quindi #!/bin/bashintroduce uno script Bash, #!/usr/bin/perlintroduce uno script Perl, ecc.

  4. Se il file inizia con \177ELF, è un eseguibile binario e lo ld.soavvia.

Leggi man execvee man ld.soper una spiegazione più dettagliata.


15
Sì, su Linux puoi fare doppio clic su Secrets.pdf senza alcun indizio dal nome che in realtà è un eseguibile;)
OrangeDog

1
@OrangeDog So che stai scherzando, ma sento che devo sottolineare che il bit eseguibile ( chmod +x) praticamente risolve questo, giusto?
wchargin,

3
@WChargin Dipende da quanto è ben educato il tuo filesystem (ad es. Una condivisione di rete montata o una partizione NTFS potrebbe impostare in modo ottimale il xbit su tutto) e da dove proviene il file (qualsiasi processo con controllo della directory potrebbe essere indotto a impostare le autorizzazioni) . Quindi, lo mitiga , ma non direi che lo risolve .
IMSoP,

2
@WChargin, tuttavia, ma penso che il suo punto che di solito i file manager non mostrano il bit eseguibile, cioè non esiste un "suggerimento per gli umani" come un'estensione.
Paul Draper,

1
Non ho mai sbagliato a fare clic su Secrets.pdf.exeperché disabilito sempre la stupida hide file extensionfunzione
phuclv

12

Il punto chiave è questo: le estensioni sono irrilevanti in qualsiasi sistema di sistema simile a Unix. Un nome file è solo un nome e non ha alcun effetto sulla possibilità di eseguire script o eseguibili compilati . Un programmatore può aggiungere .shun'estensione per designare che un file è script di shell o .pyper script Python, ma a differenza di Windows, qualsiasi unix non si preoccupa di nominare, si preoccupa delle autorizzazioni.

Ciò che conta è l'autorizzazione eseguibile concessa a un file. Con cui puoi verificare

ls -l /path/to/file

Eseguibili eseguibili

Per eseguire lo script ci sono generalmente diversi modi.

  • Se la tua directory corrente è la stessa dello script e lo script ha autorizzazioni eseguibili, puoi eseguirlo in questo modo ./my_script_name. La .directory corrente significa.
  • Se la directory corrente è diversa e lo script dispone delle autorizzazioni eseguibili, è possibile eseguirlo specificando il percorso completo: /home/user/bin/my_script_name

(I due metodi precedenti si basano sul fatto che sia stata impostata l'autorizzazione eseguibile; se il file fa parte o meno della $PATHvariabile è irrilevante. Anche la presenza della #!riga è importante; senza di essa, lo script verrà eseguito dalla shell corrente che hai aperto. Se ho cshscript senza quella linea, e prova a eseguirlo in bash con ./my_script.csh, fallirà)

  • Se lo script si trova nella directory che fa parte della $PATHvariabile, è possibile eseguirlo semplicemente chiamando il nome. Puoi chiamare il chmodcomando nella riga di comando semplicemente digitandone il nome perché è nella /bincartella. /binfa sempre parte della $PATHvariabile. In questo caso, le autorizzazioni eseguibili e l'ubicazione dell'argomento script
  • Specifica di un interprete come comando e script come argomento. In questo modo lo script servirà come file di input per l'interprete.
  • Approvvigionamento di un file. Il . filename.sho source filename.shfarà lo script essere trattata come se fosse input da tastiera, cioè come se sia stata scritta in linea di comando direttamente. In questo caso, le autorizzazioni e la posizione degli eseguibili non contano

Esempi

Esempio n. 1, in esecuzione con interprete, per eseguire le autorizzazioni

$-> ls -l abc.py                                                               
-rw-rw-r-- 1 xieerqi xieerqi 44 Apr 27 22:39 abc.py
$-> python abc.py                                                              
a
b
c

Esempio n. 2, in esecuzione con ./set di autorizzazioni eseguibile, set di righe shebang.

$-> cat abc.py                                                                 
#!/usr/bin/env python
for letter in 'a' 'b' 'c' :
   print letter
$-> ls -l abc.py
-rwxrwxr-x 1 xieerqi xieerqi 66 Apr 27 23:02 abc.py*
$-> ./abc.py                                                                   
a
b
c

Esempio n. 3, in esecuzione senza set di righe shebang (non riesce, perché bash non è in grado di leggere script Python; nessuna riga shebang assume la shell corrente come interprete)

$-> cat abc.py                                                                 
for letter in 'a' 'b' 'c' :
   print letter
$-> ./abc.py                                                                   
./abc.py: 2: ./abc.py: Syntax error: word unexpected (expecting "do")

Esempio n. 4, esecuzione di script con autorizzazioni eseguibili impostate la cartella del modulo che fa parte della $PATHvariabile

#  /home/xieerqi/bin is part of my path variable
$-> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/microchip/xc16/v1.25/bin:/opt/microchip/xc32/v1.40/bin:/opt/microchip/xc8/v1.35/bin:/home/xieerqi/bin:/home/xieerqi/bin/sh

$-> # current directory is /home/xieerqi
$-> pwd
/home/xieerqi
$-> # move the file to ~/bin
$-> mv ~/abc.py ~/bin/abc.py
$-> # now I can run it just by calling the name
$-> abc.py
/home/xieerqi/bin/abc.py: 2: /home/xieerqi/bin/abc.py: Syntax error: word unexpected (expecting "do")
$-> # Syntax error because again, no interpreter specified.                    
$-> # must add #!/usr/bin/env python
$-> vi /home/xieerqi/bin/abc.py          
$-> # after adding the line with vi text editor, we can run
$-> abc.py                                                                     
a
b
c

L'esempio n. 5, rimuovendo l'estensione, viene comunque eseguito perché le estensioni non contano, ma ha autorizzazioni ed è parte di $PATH:

$-> mv ~/bin/abc.py  ~/bin/abc                                                 
$-> abc
a
b
c

Ho eseguito il comando e ottengo questo '-rwxr-x ---'. Cosa desidero leggere il valore e come posso modificarlo?
Philip Kirkbride,

O stai dicendo che dovrei semplicemente rinominare "nomefile.sh" in "nomefile"?
Philip Kirkbride,

1
@PhilipKirkbride Il nome è irrilevante. Come si esegue il comando? Dov'è ? La directory fa parte del tuo PATH?
Sergiy Kolodyazhnyy,

@PhilipKirkbride Vorrei espandere la mia risposta in un minuto per renderlo più chiaro.
Sergiy Kolodyazhnyy,

1
Dai un'occhiata a man chmodcome impostare le autorizzazioni
Nick Mertin,

6

Buone spiegazioni qui già. Volevo solo aggiungere che idealmente non dovresti usare le estensioni dei file per gli eseguibili.

Di solito devi realizzare qualcosa di relativamente semplice e inizi con un piccolo script di shell. Nel corso del tempo inizi ad aggiungere sempre più funzionalità al tuo script, fino a quando non arriva un po 'di tempo in cui diventa non mantenibile o hai bisogno di alcune funzionalità che non puoi realizzare facilmente con uno script di shell e pensi di riscrivere questo script di shell in un'altra lingua (python , perl, ...?).

La riscrittura da zero è generalmente considerata un errore, ma per gli script può avere senso perché di solito non sono così grandi o hanno molte funzionalità. Ma supponiamo che sia possibile riscrivere da zero in qualche altra lingua, mantenendo la funzionalità e i parametri / flag dello script shell iniziale.

Gli utenti di questo script non devono essere consapevoli di questo cambio di lingua, continueranno a eseguire lo stesso comando e continueranno a funzionare.

Se il tuo script è stato nominato do-something.sh, può continuare a essere do-something.sh, ma ora è scritto in Python (per esempio), e quindi il tuo suggerimento iniziale è ora totalmente fuorviante.


4

Per eseguire file senza un'estensione che normalmente non devi fare molto, assicurati di avere (in caso di script bash) la riga shebang corretta nella prima riga:

#!/bin/bash

quindi è necessario anche rendere il file eseguibile per il sistema da

chmod 755 yourfilename

Questo è lo stesso che usare chmod +x yourfilenamei numeri è facile da spiegare.

È un numero triplo di ottali aggiunti, il primo numero indica l'utente, il secondo per il gruppo e il terzo per gli altri, più su quello che puoi trovare qui .

E se ti trovi nella stessa directory del tuo script, non dimenticare di usare in ./questo modo:

./yourfilename

Ho provato questo. Sfortunatamente nessuna differenza dai risultati originali.
Philip Kirkbride,

@PhilipKirkbride dai un'occhiata alla mia risposta riveduta, questo farà sicuramente più luce.
Videonauth,

0

Il suffisso .sh può effettivamente interferire, perché per eseguirlo devi digitare myscript.sh invece di solo myscript che non funzionerà. Meglio semplicemente chiamarlo "myscript" senza il suffisso .sh, e un rapido utilizzo del comando "file" ti dirà se è un eseguibile binario (formato ELF su linux) o uno script di shell, o qualunque altro tipo di script.

QDOS (Quick and Dirty Operating System, successivamente ribattezzato "DOS" da IBM dopo che Mirosoft lo ha piratato e venduto illegalmente a loro) e altri furti economici di CP / M, comprese le finestre, mescolano tutto questo perché su quei sistemi non c'è cosa come eseguire permessi sui file. Ciò ha portato a innumerevoli problemi di sicurezza negli ultimi 30-40 anni. In realtà solo pochi minuti fa ho ricevuto diverse e-mail indesiderate con un file zip intrappolato traboccante rinominato in MYPICTURE.JPG.zip :)

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.