Odpowiedź @ milne działa, ale subprocess.call()daje niewiele informacji zwrotnych.
Wolę używać subprocess.check_output(), abyś mógł przeanalizować, co zostało wydrukowane na standardowe wyjście:
import subprocess
res = subprocess.check_output(["sudo","apt","update"])for line in res.splitlines():# process the output line by line
check_output zgłasza błąd przy zerowym wyjściu z wywołanej komendy
Pamiętaj, że to nie wywołuje bashani innej powłoki, jeśli nie podasz shellargumentu słowa kluczowego dla funkcji (to samo dotyczy subprocess.call(), i nie powinieneś, jeśli nie jest to konieczne, ponieważ stanowi zagrożenie bezpieczeństwa), bezpośrednio wywołuje Komenda.
Jeśli zauważysz, że wykonujesz wiele (różnych) wywołań poleceń z Pythona, możesz przyjrzeć się pionowi . Dzięki temu możesz zrobić (IMO) bardziej czytelny:
from plumbum.cmd import sudo, apt, echo, cut
res = sudo[apt["update"]]()
chain = echo["hello"]| cut["-c","2-"]
chain()
Czy zaleca się użycie ( os.popenlub os.system), np .: res = os.popen('sudo apt update').read()? @Anthon
alper
1
@alper Przeczytaj 0324 python.org/dev/peps/pep-0324 . To wyjaśnia uzasadnienie dla podejmowania subprocesschoć os.systemi os.popenjuż istniał. Takie PEP nie są łatwe do zaakceptowania. Kilka osób zastanowiło się nad tym znacznie więcej niż ty lub ja. I subprocesspoprawił się od 2003 roku, pozostałe wciąż są dostępne dla kompatybilności wstecznej. Czy os.systemzredagowałeś stronę podręcznika: Moduł podprocesu zapewnia potężniejsze możliwości tworzenia nowych procesów i wyszukiwania ich wyników; korzystanie z tego modułu jest lepsze niż korzystanie z tej funkcji.
Anthon
1
@alper Tak, możesz. Jak już wskazałem, jest to potencjalne zagrożenie bezpieczeństwa, więc nie wiem, dlaczego uważasz, że jest to zalecane. A inwokowanie sudotylko pogorszy to. Może lepszym rozwiązaniem jest użycie python-apt (sam tego nie analizowałem).
Anthon
1
@alper w takim przypadku poważnie przyjrzyj się pionowi , warto z tym przyspieszyć.
Anthon
1
@alper Jeśli korzystasz z Python3, musisz to zrobić, w Python2 nie. Nie używaj komentarzy tutaj jako systemu czatu. Jeśli masz pytanie, opublikuj je jako takie.
Anthon
8
Możliwe jest użycie bash jako programu, z parametrem -c do wykonania poleceń:
Jeśli chcesz, aby skrypt zakończył się w przypadku niepowodzenia polecenia, możesz rozważyć użycie check_call()zamiast samodzielnego analizowania kodu powrotu:
dało mi to następujący ślad: Traceback (most recent call last): File "/home/Dremor/test.py", line 3, in <module> subprocess.call('sudo', 'yum', 'update') File "/usr/lib64/python3.4/subprocess.py", line 537, in call with Popen(*popenargs, **kwargs) as p: File "/usr/lib64/python3.4/subprocess.py", line 767, in __init__ raise TypeError("bufsize must be an integer") TypeError: bufsize must be an integer (używam yum, ponieważ używam Fedory jako głównego systemu operacyjnego)
Dremor,
3
Zapomniałeś nawiasów kwadratowych
Milind Dumbare
1
Zauważ też, że subprocess.call()blokuje się, a subprocess.Popen()nie blokuje.
heemayl
Co rozumiesz przez „blokowanie”? @heemayl
alper
2
Możesz także użyć „os.popen”.
Przykład:
import os
command = os.popen('ls -al')print(command.read())print(command.close())
Wynik:
total 16
drwxr-xr-x 2 root root 4096 ago 1321:53.
drwxr-xr-x 4 root root 4096 ago 1301:50..-rw-r--r--1 root root 1278 ago 1321:12 bot.py
-rw-r--r--1 root root 77 ago 1321:53 test.py
None
Odpowiedzi:
Odpowiedź @ milne działa, ale
subprocess.call()
daje niewiele informacji zwrotnych.Wolę używać
subprocess.check_output()
, abyś mógł przeanalizować, co zostało wydrukowane na standardowe wyjście:check_output
zgłasza błąd przy zerowym wyjściu z wywołanej komendyPamiętaj, że to nie wywołuje
bash
ani innej powłoki, jeśli nie podaszshell
argumentu słowa kluczowego dla funkcji (to samo dotyczysubprocess.call()
, i nie powinieneś, jeśli nie jest to konieczne, ponieważ stanowi zagrożenie bezpieczeństwa), bezpośrednio wywołuje Komenda.Jeśli zauważysz, że wykonujesz wiele (różnych) wywołań poleceń z Pythona, możesz przyjrzeć się pionowi . Dzięki temu możesz zrobić (IMO) bardziej czytelny:
źródło
os.popen
lubos.system
), np .:res = os.popen('sudo apt update').read()
? @Anthonsubprocess
choćos.system
ios.popen
już istniał. Takie PEP nie są łatwe do zaakceptowania. Kilka osób zastanowiło się nad tym znacznie więcej niż ty lub ja. Isubprocess
poprawił się od 2003 roku, pozostałe wciąż są dostępne dla kompatybilności wstecznej. Czyos.system
zredagowałeś stronę podręcznika: Moduł podprocesu zapewnia potężniejsze możliwości tworzenia nowych procesów i wyszukiwania ich wyników; korzystanie z tego modułu jest lepsze niż korzystanie z tej funkcji.sudo
tylko pogorszy to. Może lepszym rozwiązaniem jest użycie python-apt (sam tego nie analizowałem).Możliwe jest użycie bash jako programu, z parametrem -c do wykonania poleceń:
Przykład:
źródło
Podproces moduł został zaprojektowany, aby to zrobić:
Jeśli chcesz, aby skrypt zakończył się w przypadku niepowodzenia polecenia, możesz rozważyć użycie
check_call()
zamiast samodzielnego analizowania kodu powrotu:źródło
Traceback (most recent call last): File "/home/Dremor/test.py", line 3, in <module> subprocess.call('sudo', 'yum', 'update') File "/usr/lib64/python3.4/subprocess.py", line 537, in call with Popen(*popenargs, **kwargs) as p: File "/usr/lib64/python3.4/subprocess.py", line 767, in __init__ raise TypeError("bufsize must be an integer") TypeError: bufsize must be an integer
(używam yum, ponieważ używam Fedory jako głównego systemu operacyjnego)subprocess.call()
blokuje się, asubprocess.Popen()
nie blokuje.Możesz także użyć „os.popen”.
Przykład:
Wynik:
źródło
użyj modułu podprocesu
źródło