2012-12-31 12 views
10

Używając Pythona na Mac OS, chciałbym otworzyć plik do pisania i umieścić w nim komendy powłoki. Później uruchomić w terminalu.Ustaw bit wykonania dla pliku przy użyciu pythona

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

Spowoduje to utworzenie pliku, ale nie mogę zrozumieć, jak ustawić bit wykonywania więc kiedy go uruchomić w terminalu nie dostanie:

sh: my_script.sh: Permission denied 
+0

Użyj podprocesu, aby ustawić odpowiednie uprawnienia do pliku - http://docs.python.org/2/library/subprocess.html – theharshest

+0

@theharshest: Jak zrobiłbyś to z 'podprocesorem'? (Przypuszczam, że mógłbyś 'check_call (['chmod', 'a + x', 'myscript.sh'])), w ten sam sposób, w jaki można" check_call (['echo', 'foo']) 'zamiast 'print ('foo')' jeśli naprawdę chcesz, ale ... dlaczego?) – abarnert

Odpowiedz

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

Wybierz wartość właściwie jednak. Niektóre wartości mogą nie być bezpieczne.

+0

Działa - dzięki. –

+4

Musisz użyć '0o744' dla kompatybilności z Python 3. – asmeurer

10

Zawsze można to zrobić z powłoki terminali, przed uruchomieniem go, używając chmod:

chmod a+x my_script.sh 

Jeśli chcesz to zrobić z poziomu Pythona, można użyć chmodfchmod lub w module os. Skoro już masz plik otwarty, zrobiłbym to ostatnie:

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) 

Niestety, jak widać, nie ma bezpośredni odpowiednik chmod a+x dodanie flagi x dla wszystkich, pozostawiając wszystko inne w spokoju. Ale można zrobić to samo narzędzie chmod wiersza polecenia faktycznie robi: stat plik (lub w tym przypadku, fstat) aby istniejące uprawnienia, a następnie modyfikować je:

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)) 

(nie robić rzeczywiście potrzebujesz kroku S_IMODE na większości platform, ponieważ albo st_mode nie ma żadnych dodatkowych bitów, albo (f) chmod nieszkodliwie je ignoruje - tak jak robi to OS X. Ale lepiej zrobić to, co trzeba, aby twój kod był przenośny i przyszłościowy -proof.)

Większość ludzi uważa "przyjazne" nazwy, takie jak S_IXUSR za niezbyt przyjazne, a gdy nauczysz się myśleć o trybach pod względem ósemkowe to rzeczywiście łatwiej niż starając się zapamiętać jak POSIX skraca rzeczy, więc może wolisz to:

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) 

111 oznacza wykonywalny przez użytkownika, grupy i inne (takie same Rzecz w tym, że | różnych bitów ST_IX*) i 7777 to wszystkie bity, do których możesz przejść (f) chmod (to samo, co robi S_IMODE).

Powiązane problemy