2012-12-31 9 views
10

Utilizzando python su Mac OS, vorrei aprire un file per la scrittura e inserirvi alcuni comandi di shell. Successivamente verrà eseguito nel terminale.Imposta bit di esecuzione per un file usando python

with open("my_script.sh", "w") as fd: 
    fd.write("#!/bin/sh\n") 
    fd.write("echo $PATH\n") 

Questo creerà il file, ma non riuscivo a capire come impostare il bit di esecuzione in modo che quando l'eseguo nel terminale non voglio entrare:

sh: my_script.sh: Permission denied 
+0

Utilizzare il sottoprocesso per impostare le autorizzazioni appropriate per il file: http://docs.python.org/2/library/subprocess.html – theharshest

+0

@theharshest: Come si farebbe con il sottoprocesso? (Suppongo che tu possa 'check_call (['chmod', 'a + x', 'myscript.sh'])', nello stesso modo in cui puoi 'check_call (['echo', 'foo'])' invece di 'print ('foo')' se lo vuoi davvero, ma ... perché?) – abarnert

risposta

18
import os 
os.chmod("my_script.sh", 0744) 

Scegli il valore correttamente però. Alcuni valori potrebbero non essere sicuri.

+0

Funziona - grazie. –

+4

È necessario utilizzare '0o744' per la compatibilità con Python 3. – asmeurer

10

Puoi sempre farlo dalla shell Terminal, prima di eseguirlo, usando chmod:

chmod a+x my_script.sh 

Se si vuole farlo da Python, è possibile utilizzare uno o chmodfchmod nel modulo os. Dal momento che avete già il file aperto, mi piacerebbe fare il secondo:

with open("my_script.sh", "w") as fd: 
    fd.write("#!/bin/sh\n") 
    fd.write("echo $PATH\n") 
    os.fchmod(fd.fileno(), stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH | stat.S_IXOTH) 

Purtroppo, come potete vedere, non c'è alcun equivalente diretto chmod a+x aggiungendo la bandiera x per tutti, lasciando tutto il resto da solo. Ma si può fare la stessa cosa lo strumento chmod della riga di comando in realtà fa: stat il file (o, in questo caso, fstat) per ottenere le autorizzazioni esistenti, quindi modificarli:

with open("my_script.sh", "w") as fd: 
    fd.write("#!/bin/sh\n") 
    fd.write("echo $PATH\n") 
    mode = os.fstat(fd.fileno()).st_mode 
    mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH 
    os.fchmod(fd.fileno(), stat.S_IMODE(mode)) 

(Non lo sai in realtà hanno bisogno del passo S_IMODE sulla maggior parte delle piattaforme, perché o st_mode non ha bit aggiuntivi, o (f) chmod li ignora in modo innocuo, come fa OS X. Ma è meglio fare la cosa giusta, rendere il tuo codice portatile e futuro -proof.)

La maggior parte delle persone considera i nomi "amici" come S_IXUSR non particolarmente adatti, e una volta che si impara a pensare a modi in termini ottale in realtà è più facile che cercare di ricordare come POSIX abbrevia le cose, in modo da può preferire questo:

with open("my_script.sh", "w") as fd: 
    fd.write("#!/bin/sh\n") 
    fd.write("echo $PATH\n") 
    mode = os.fstat(fd.fileno()).st_mode 
    mode |= 0o111 
    os.fchmod(fd.fileno(), mode & 0o7777) 

Il 111 significa eseguibile per utente, gruppo, e altri (lo stesso cosa come | dei vari ST_IX* bit) e 7777 sono tutti bit che è possibile passare a (f) chmod (la stessa cosa che fa lo S_IMODE).

Problemi correlati