Jak wykonać program lub wywołać polecenie systemowe z Pythona?

Jak wywołać zewnętrzne polecenie (jakbym wpisał je w powłoce Uniksa lub wierszu polecenia systemu Windows) ze skryptu Pythona?

Author: rishta, 2008-09-18

30 answers

Użyj subprocess moduł w bibliotece standardowej:

import subprocess
subprocess.run(["ls", "-l"])

Zaletą subprocess.run over os.system jest to, że jest bardziej elastyczny (można uzyskać stdout, stderr, kod statusu "prawdziwy" , lepiej obsługa błędów itp...).

Nawet dokumentacja dla os.system zaleca użycie subprocess zamiast:

Moduł subprocess zapewnia mocniejsze zaplecze do tworzenia nowych procesów i pobieranie ich wyników; korzystanie z tego modułu jest lepsze niż korzystanie z tej funkcji. Zobacz sekcję zastępowanie starszych funkcji modułem podprocesowym W subprocess dokumentacja przydatnych przepisów.

W Pythonie 3.4 i wcześniejszych, użyj subprocess.call zamiast .run:

subprocess.call(["ls", "-l"])
 4965
Author: David Cournapeau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-10 09:15:43

Oto podsumowanie sposobów wywoływania programów zewnętrznych oraz zalet i wad każdego z nich:

  1. os.system("some_command with args") przekazuje polecenie i argumenty do powłoki systemu. Jest to miłe, ponieważ w ten sposób można uruchomić wiele poleceń naraz i skonfigurować rury i przekierowanie wejścia/wyjścia. Na przykład:

    os.system("some_command < input_file | another_command > output_file")  
    

Jednak, chociaż jest to wygodne, musisz ręcznie obsługiwać ucieczkę znaków powłoki, takich jak spacje itp. Z drugiej strony, pozwala to również na uruchamianie poleceń, które są po prostu poleceniami powłoki, a nie zewnętrznymi programami. Zobacz dokumentację .

  1. stream = os.popen("some_command with args") zrobi to samo co os.system z tym wyjątkiem, że daje obiekt podobny do pliku, który można użyć do uzyskania dostępu do standardowego wejścia/wyjścia dla tego procesu. Istnieją 3 inne warianty popen, które obsługują we / wy nieco inaczej. Jeśli przekazujesz wszystko jako ciąg znaków, wtedy twoje polecenie jest przekazywane do powłoki; jeśli przekaż je jako listę, a nie musisz się martwić o ucieczkę przed niczym. Zobacz dokumentację .

  2. Klasa Popen modułu subprocess. Ma to na celu zastąpienie os.popen, ale ma tę zaletę, że jest nieco bardziej skomplikowana, ponieważ jest tak kompleksowa. Na przykład:

    print subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read()
    

    Zamiast:

    print os.popen("echo Hello World").read()
    

    Ale miło jest mieć wszystkie opcje w jednej zunifikowanej klasie zamiast 4 różnych funkcji popen. Zobacz dokumentację .

  3. Funkcja call z modułu subprocess. Jest to w zasadzie podobne do klasy Popen i pobiera wszystkie te same argumenty, ale po prostu czeka, aż Komenda zakończy się i poda kod powrotu. Na przykład:

    return_code = subprocess.call("echo Hello World", shell=True)  
    

    Patrz dokumentacja .

  4. Jeśli korzystasz z Pythona 3.5 lub nowszego, możesz użyć nowego subprocess.run funkcja, która jest bardzo podobna do powyższego, ale jeszcze bardziej elastyczna i zwraca a CompletedProcess obiekt po zakończeniu wykonywania polecenia.

  5. Moduł os posiada również wszystkie funkcje fork/exec/spawn, które można mieć w programie C, ale nie polecam ich używać bezpośrednio.

Moduł subprocess powinien być tym, czego używasz.

Na koniec należy pamiętać, że dla wszystkich metod, w których przekazujesz ostateczne polecenie do wykonania przez powłokę jako łańcuch znaków i jesteś odpowiedzialny za jego ucieczkę. są poważne implikacje bezpieczeństwa jeśli jakakolwiek część ciągu, który przekazujesz, nie może być w pełni zaufana. Na przykład, jeśli użytkownik wprowadza jakąś / dowolną część łańcucha. Jeśli nie masz pewności, używaj tych metod tylko ze stałymi. Aby dać Ci podpowiedź o implikacjach rozważ ten kod:

print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read()

I wyobraź sobie, że użytkownik wprowadza coś "moja mama mnie nie kochała & & rm-rf/", co może wymazać cały system plików.

 3076
Author: Eli Courtwright,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-04 02:34:49

Typowa realizacja:

import subprocess

p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
    print line,
retval = p.wait()

Możesz robić co chcesz z stdout danymi w rurze. W rzeczywistości, można po prostu pominąć te parametry (stdout= i stderr=) i będzie zachowywać się jak os.system().

 377
Author: EmmEff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-04 02:33:47

Kilka wskazówek na temat odłączenia procesu potomnego od wywołującego (uruchomienie procesu potomnego w tle).

Załóżmy, że chcesz rozpocząć długie zadanie ze skryptu CGI. Oznacza to, że proces potomny powinien żyć dłużej niż proces wykonywania skryptu CGI.

Klasyczny przykład z dokumentacji modułu podprocesowego to:

import subprocess
import sys

# Some code here

pid = subprocess.Popen([sys.executable, "longtask.py"]) # Call subprocess

# Some more code here

Chodzi o to, że nie chcesz czekać w linii 'call podprocess' aż do longtask.py jest skończony. Ale nie jest jasne, co dzieje się po linii 'some more code here' z przykładu.

Moją docelową platformą był FreeBSD, ale rozwój był na Windows, więc najpierw stanąłem przed problemem na Windows.

W systemie Windows (Windows XP) proces nadrzędny nie zakończy się, dopóki longtask.py zakończył pracę. To nie jest to, czego chcesz w skrypcie CGI. Problem nie jest specyficzny dla Pythona; w społeczności PHP problemy są takie same.

Rozwiązaniem jest przejście procesu DETACHED_PROCESS Znacznik Creation do podstawowej funkcji CreateProcess w Windows API. Jeśli zdarzy ci się zainstalować pywin32, możesz zaimportować flagę z modułu win32process, w przeciwnym razie powinieneś zdefiniować ją samodzielnie:

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable, "longtask.py"],
                       creationflags=DETACHED_PROCESS).pid

/* UPD 2015.10.27 @eryksun w komentarzu poniżej zaznaczono, że poprawna semantycznie flaga to CREATE_NEW_CONSOLE (0x00000010) * /

Na FreeBSD mamy jeszcze jeden problem: gdy proces rodzic jest skończony, kończy również procesy potomne. Oraz to nie jest to, co chcesz w skrypcie CGI albo. Niektóre eksperymenty wykazały, że problemem wydaje się być dzielenie sys.stdout. I rozwiązanie robocze było następujące:

pid = subprocess.Popen([sys.executable, "longtask.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

Nie sprawdzałem kodu na innych platformach i nie znam przyczyn takiego zachowania na FreeBSD. Jeśli ktoś wie, proszę podzielić się swoimi pomysłami. Googling przy uruchamianiu procesów w tle w Pythonie nie rzuca jeszcze żadnego światła.

 242
Author: newtover,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-29 21:46:11
import os
os.system("your command")

Zauważ, że jest to niebezpieczne, ponieważ polecenie nie jest czyszczone. Pozostawiam to do google dla odpowiedniej dokumentacji na temat modułów " os " i "sys". Istnieje kilka funkcji (exec * I spawn*), które będą robić podobne rzeczy.

 165
Author: nimish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-03 17:10:00

Zalecałbym użycie modułu podprocesu zamiast systemu operacyjnego.system, ponieważ nie powłoki ucieczki dla Ciebie i dlatego jest znacznie bezpieczniejsze.

subprocess.call(['ping', 'localhost'])
 157
Author: sirwart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-24 01:01:46
import os
cmd = 'ls -al'
os.system(cmd)

Jeśli chcesz zwrócić wyniki polecenia, możesz użyć os.popen. Jest to jednak przestarzałe od wersji 2.6 na rzecz modułu podprocesu , który dobrze obejmował inne odpowiedzi.

 151
Author: Alexandra Franks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-26 16:53:05

Istnieje wiele różnych bibliotek, które umożliwiają wywoływanie zewnętrznych poleceń za pomocą Pythona. Dla każdej biblioteki podałem opis i pokazałem przykład wywołania zewnętrznego polecenia. Poleceniem, którego użyłem jako przykładu jest ls -l (Lista wszystkich plików). Jeśli chcesz dowiedzieć się więcej o którejkolwiek z wymienionych przeze mnie bibliotek i powiązać dokumentację dla każdej z nich.

Źródła:

Są to wszystkie biblioteki:

Mam nadzieję, że to pomoże Ci podjąć decyzję, z której biblioteki korzystać:)

Podproces

Podproces pozwala na wywołanie zewnętrznego polecenia i podłączyć je do ich rur wejściowych/wyjściowych / błędów (stdin, stdout i stderr). Podproces jest domyślnym wyborem dla uruchamiania poleceń, ale czasami inne moduły są lepsze.

subprocess.run(["ls", "-l"]) # Run command
subprocess.run(["ls", "-l"], stdout=subprocess.PIPE) # This will run the command and return any output
subprocess.run(shlex.split("ls -l")) # You can also use the shlex library to split the command

Os

System Operacyjny jest używany do "funkcji zależnych od systemu operacyjnego". Może być również używany do wywoływania zewnętrznych poleceń z os.system i os.popen (Uwaga: Istnieje również podproces.popen). system operacyjny zawsze uruchomi powłokę i jest prostą alternatywą dla osób, które nie potrzebują do, lub Nie wiem, jak używać subprocess.run.

os.system("ls -l") # run command
os.popen("ls -l").read() # This will run the command and return any output

Sh

SH jest podprocesowym interfejsem, który pozwala wywoływać programy tak, jakby były funkcjami. Jest to przydatne, jeśli chcesz uruchomić polecenie wiele razy.

sh.ls("-l") # Run command normally
ls_cmd = sh.Command("ls") # Save command as a variable
ls_cmd() # Run command as if it were a function

Plumbum

Plumbum jest biblioteką dla" skryptowych " programów Pythona. Możesz wywoływać programy takie jak funkcje jak w sh. Plumbum jest przydatny, jeśli chcesz uruchomić rurociąg bez shell.

ls_cmd = plumbum.local("ls -l") # get command
ls_cmd() # run command

Pexpect

Pexpect pozwala na odradzanie aplikacji potomnych, kontrolowanie ich i znajdowanie wzorców w ich wynikach. Jest to lepsza alternatywa dla podprocesu dla poleceń, które oczekują tty na Uniksie.

pexpect.run("ls -l") # Run command as normal
child = pexpect.spawn('scp foo [email protected]:.') # Spawns child application
child.expect('Password:') # When this is the output
child.sendline('mypassword')

Tkanina

Fabric jest biblioteką Pythona 2.5 i 2.7. Pozwala na wykonywanie lokalnych i zdalnych poleceń powłoki. Fabric jest prostą alternatywą dla uruchamiania poleceń w bezpiecznej powłoce (SSH)

fabric.operations.local('ls -l') # Run command as normal
fabric.operations.local('ls -l', capture = True) # Run command and receive output

Envoy

Envoy jest znany jako "podproces dla ludzi". Jest używany jako wygodna owijarka wokół modułu subprocess.
r = envoy.run("ls -l") # Run command
r.std_out # get output

Komendy

commands zawiera funkcje wrappera dla os.popen, ale został usunięty z Pythona 3, ponieważ subprocess jest lepszą alternatywą.

Edycja została oparta na komentarzu J. F. Sebastiana.

 107
Author: Tom Fuller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-28 23:14:34

Zawsze używam fabric do takich rzeczy jak:

from fabric.operations import local
result = local('ls', capture=True)
print "Content:/n%s" % (result, )

Ale to wydaje się być dobrym narzędziem: sh (Python subprocess interface) .

Spójrz na przykład:

from sh import vgdisplay
print vgdisplay()
print vgdisplay('-v')
print vgdisplay(v=True)
 79
Author: Jorge E. Cardona,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-29 21:47:58

Z biblioteką standardową

Użyj modułu podprocesu (Python 3):

import subprocess
subprocess.run(['ls', '-l'])

Jest to zalecany standardowy sposób. Jednak bardziej skomplikowane zadania (rury, wyjście, wejście itp.) może być żmudne konstruowanie i pisanie.

Uwaga dotycząca wersji Pythona: jeśli nadal używasz Pythona 2, podproces.call Działa w podobny sposób.

ProTip: shlex.split może pomóc w przetworzeniu polecenia dla run, call, oraz inne funkcje subprocess W przypadku, gdy nie chcesz (lub nie możesz!) podaj je w formie list:

import shlex
import subprocess
subprocess.run(shlex.split('ls -l'))

Z zewnętrznymi zależnościami

Jeśli nie masz nic przeciwko zewnętrznym zależnościom, użyj plumbum :

from plumbum.cmd import ifconfig
print(ifconfig['wlan0']())

Jest to najlepsza subprocess owijarka. Jest wieloplatformowy, tzn. działa zarówno na systemach Windows, jak i Unix-podobnych. Install by pip install plumbum.

Kolejną popularną biblioteką jest sh :

from sh import ifconfig
print(ifconfig('wlan0'))

Jednak sh porzucił wsparcie Dla Windows, więc nie jest tak zajebiście jak kiedyś. Install by pip install sh.

 79
Author: Honza Javorek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-29 21:54:25

Sprawdź też bibliotekę Pythona "pexpect".

Pozwala na interaktywne sterowanie zewnętrznymi programami / poleceniami, nawet ssh, ftp, telnet, itp. Możesz po prostu wpisać coś w stylu:

child = pexpect.spawn('ftp 192.168.0.24')

child.expect('(?i)name .*: ')

child.sendline('anonymous')

child.expect('(?i)password')
 77
Author: athanassis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-28 23:02:27

Jeśli potrzebujesz wyjścia z wywołanego polecenia, następnie możesz użyć podprocesu .check_output (Python 2.7+).

>>> subprocess.check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'

Zwróć również uwagę na parametr powłoki.

Jeśli powłoką jest True, określone polecenie zostanie wykonane przez powłokę. Może to być przydatne, jeśli używasz Pythona głównie do ulepszonego przepływu sterowania, który oferuje w większości powłok systemowych i nadal chcesz wygodny dostęp do innych funkcji powłoki, takich jak rury powłoki, nazwa pliku wildcards, rozszerzenie zmiennej środowiskowej i rozszerzenie ~ do katalogu domowego użytkownika. Należy jednak pamiętać, że sam Python oferuje implementacje wielu funkcji podobnych do powłoki (w szczególności, glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser(), i shutil).

 75
Author: Facundo Casco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-03 20:18:34

Tak uruchamiam moje polecenia. Ten kod ma wszystko, czego potrzebujesz w zasadzie

from subprocess import Popen, PIPE
cmd = "ls -l ~/"
p = Popen(cmd , shell=True, stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
print "Return code: ", p.returncode
print out.rstrip(), err.rstrip()
 59
Author: Usman Khan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-28 05:44:05

Aktualizacja:

subprocess.run jest zalecanym podejściem od Pythona 3.5 , jeśli twój kod nie musi zachować zgodności z wcześniejszymi wersjami Pythona. Jest bardziej spójny i oferuje podobną łatwość obsługi jak Envoy. (Orurowanie nie jest jednak tak proste. Zobacz to pytanie, jak .)

Oto kilka przykładów z dokumentacji.

Uruchom proces:

>>> subprocess.run(["ls", "-l"])  # Doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)

Podniesienie przy nieudanym uruchomieniu:

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

Capture wyjście:

>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

Oryginalna ODPOWIEDŹ:

Zalecam wypróbowanie Envoy . Jest to wrapper dla podprocesu, który z kolei ma zastąpić starsze moduły i funkcje. Envoy jest podprocesem dla ludzi.

Przykładowe użycie z README :

>>> r = envoy.run('git config', data='data to pipe in', timeout=2)

>>> r.status_code
129
>>> r.std_out
'usage: git config [options]'
>>> r.std_err
''

Fajki też:

>>> r = envoy.run('uptime | pbcopy')

>>> r.command
'pbcopy'
>>> r.status_code
0

>>> r.history
[<Response 'uptime'>]
 58
Author: Joe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-29 21:52:33

Użycie podproces.

...lub dla bardzo prostej komendy:

import os
os.system('cat testfile')
 48
Author: Ben Hoffstein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-29 21:39:08

Wywołanie zewnętrznego polecenia w Pythonie

Proste, użyj subprocess.run, które zwraca CompletedProcess obiekt:

>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)
Dlaczego?

Od wersji Pythona 3.5 dokumentacja zaleca podproces .run :

Zalecanym podejściem do wywoływania podprocesów jest użycie funkcji run () dla wszystkich przypadków użycia, które może obsłużyć. W bardziej zaawansowanych przypadkach można użyć interfejsu Popen bezpośrednio.

Oto przykład najprostsze możliwe użycie - i robi dokładnie tak, jak prosi się:

>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)

run oczekuje na pomyślne zakończenie polecenia, a następnie zwraca obiekt CompletedProcess. Może zamiast tego podnieść TimeoutExpired (Jeśli podasz mu argument timeout=) lub CalledProcessError (jeśli się nie powiedzie i zdasz check=True).

Jak można wywnioskować z powyższego przykładu, stdout i stderr są domyślnie przesyłane do własnych stdout i stderr.

Możemy sprawdzić zwrócony obiekt i zobaczyć polecenie, które zostało podane i returncode:

>>> completed_process.args
'python --version'
>>> completed_process.returncode
0

Przechwytywanie wyjścia

Jeśli chcesz przechwycić wyjście, możesz przekazać {[18] } do odpowiedniego stderr lub stdout:

>>> cp = subprocess.run('python --version', 
                        stderr=subprocess.PIPE, 
                        stdout=subprocess.PIPE)
>>> cp.stderr
b'Python 3.6.1 :: Anaconda 4.4.0 (64-bit)\r\n'
>>> cp.stdout
b''

(uważam za interesujące i nieco sprzeczne z intuicją, że informacje o wersji są umieszczane na stderr zamiast na stdout.)

Podaj listę poleceń

Można łatwo przejść od ręcznego dostarczania ciągu poleceń (jak sugeruje pytanie) do dostarczania ciągu zbudowanego programowo. nie buduj łańcuchów programowo.To potencjalny problem bezpieczeństwa. Lepiej założyć, że nie ufasz wkładowi.

>>> import textwrap
>>> args = ['python', textwrap.__file__]
>>> cp = subprocess.run(args, stdout=subprocess.PIPE)
>>> cp.stdout
b'Hello there.\r\n  This is indented.\r\n'

Uwaga, tylko args powinny być przekazywane pozycyjnie.

Pełny Podpis

Oto faktyczny podpis w źródle i jak pokazano przez help(run):

def run(*popenargs, input=None, timeout=None, check=False, **kwargs):

popenargs i kwargs są podane konstruktorowi Popen. input może być ciągiem bajtów (lub unicode, jeśli określi kodowanie lub universal_newlines=True), który będzie przesyłany do podprocesu stdin.

Dokumentacja opisuje timeout= i check=True lepiej niż mogłem:

Argument timeout jest przekazywany do Popen.communicate (). Jeśli timeout / align = "center" bgcolor = "# e0ffe0 " / król Danii / / align = center / Na Wyjątek TimeoutExpired zostanie ponownie podniesiony po zakończeniu procesu potomnego / align = "left" /

Jeśli check jest prawdziwe, a proces kończy pracę z niezerowym kodem wyjścia, a Zostanie wywołany wyjątek CalledProcessError. Atrybuty tego Exception hold argumenty, kod wyjścia oraz stdout i stderr if zostali schwytani.

I ten przykład dla {[17] } jest lepszy niż ten, który mógłbym wymyślić:

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

Rozszerzony Podpis

Oto Rozszerzony podpis podany w dokumentacji:]}
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, 
shell=False, cwd=None, timeout=None, check=False, encoding=None, 
errors=None)

Zauważ, że oznacza to, że tylko lista args powinna być przekazywana pozycyjnie. Więc podaj pozostałe argumenty jako argumenty słów kluczowych.

Popen

Kiedy zamiast tego użyj Popen? Trudno byłoby znaleźć przypadek użycia oparty na samych argumentach. Bezpośrednie użycie Popen daje jednak dostęp do jego metod, w tym poll, 'send_signal', 'terminate' i 'wait'.

Oto Popen podpis podany w źródle . Myślę, że jest to najbardziej precyzyjna enkapsulacja informacji (w przeciwieństwie do help(Popen)):

def __init__(self, args, bufsize=-1, executable=None,
             stdin=None, stdout=None, stderr=None,
             preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
             shell=False, cwd=None, env=None, universal_newlines=False,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False,
             pass_fds=(), *, encoding=None, errors=None):

Ale bardziej pouczające jest Popen dokumentacja :

subprocess.Popen(args, bufsize=-1, executable=None, stdin=None,
                 stdout=None, stderr=None, preexec_fn=None, close_fds=True,
                 shell=False, cwd=None, env=None, universal_newlines=False,
                 startupinfo=None, creationflags=0, restore_signals=True,
                 start_new_session=False, pass_fds=(), *, encoding=None, errors=None)

Uruchamia program potomny w nowym procesie. W POSIX Klasa używa os.execvp () - podobne zachowanie do wykonania programu potomnego. Na Windows, Klasa używa funkcji Windows CreateProcess (). Argumenty do Popen są następujące.

Zrozumienie pozostałej dokumentacji na Popen zostanie pozostawione jako ćwiczenie dla czytelnika.

 39
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 16:37:52

os.system jest ok, ale trochę przestarzałe. Nie jest też zbyt bezpieczny. Zamiast tego spróbuj subprocess. subprocess nie wywołuje sh bezpośrednio i dlatego jest bezpieczniejszy niż os.system.

Więcej informacji Tutaj .

 38
Author: Martin W,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-10 13:25:05

Istnieje również Plumbum

>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand(<LocalPath /bin/ls>)
>>> ls()
u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n'
>>> notepad = local["c:\\windows\\notepad.exe"]
>>> notepad()                                   # Notepad window pops up
u''                                             # Notepad window is closed by user, command returns
 35
Author: stuckintheshuck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-10 17:41:13

To może być takie proste:

import os
cmd = "your command"
os.system(cmd)
 30
Author: Samadi Salahedine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 12:06:53

Użycie:

import os

cmd = 'ls -al'

os.system(cmd)

System Operacyjny-moduł ten zapewnia przenośny sposób korzystania z funkcjonalności zależnej od systemu operacyjnego.

Aby uzyskać więcej funkcji os, tutaj znajduje się dokumentacja.

 29
Author: Priyankara,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-28 23:05:23

Bardzo lubię shell_command za swoją prostotę. Jest zbudowany na module podprocesowym.

Oto przykład z dokumentacji:

>>> from shell_command import shell_call
>>> shell_call("ls *.py")
setup.py  shell_command.py  test_shell_command.py
0
>>> shell_call("ls -l *.py")
-rw-r--r-- 1 ncoghlan ncoghlan  391 2011-12-11 12:07 setup.py
-rw-r--r-- 1 ncoghlan ncoghlan 7855 2011-12-11 16:16 shell_command.py
-rwxr-xr-x 1 ncoghlan ncoghlan 8463 2011-12-11 16:17 test_shell_command.py
0
 28
Author: mdwhatcott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-29 21:49:06

Jest tu inna różnica, o której wcześniej nie wspomniano.

subprocess.Popen wykonuje polecenie jako podproces. W moim przypadku muszę wykonać plik , który musi komunikować się z innym programem, .

Próbowałem podprocesu i wykonanie się powiodło. Jednak nie mógł się komunikować z . Wszystko jest normalne, gdy uruchamiam oba z terminala.

Jeszcze jeden: (Uwaga: kwrite zachowuje się inaczej niż inne aplikacje. Jeśli wypróbujesz poniższe z Firefox, wyniki nie będą takie same.)

Jeśli spróbujesz os.system("kwrite"), przepływ programu zawiesza się, dopóki użytkownik nie zamknie kwrite. Aby przezwyciężyć, że próbowałem zamiast os.system(konsole -e kwrite). Tym razem program nadal działał, ale kwrite stał się podprocesem konsoli.

Każdy uruchomi kwrite nie będący podprocesem (tzn. w monitorze systemowym musi pojawić się na lewej krawędzi drzewa).

 24
Author: Atinc Delican,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-03 20:14:32

os.system nie pozwala na przechowywanie wyników, więc jeśli chcesz przechowywać wyniki na jakiejś liście lub czymś takim, subprocess.call działa.

 24
Author: Saurabh Bangad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-29 21:48:26

subprocess.check_call jest to wygodne, jeśli nie chcesz testować wartości zwrotnych. Rzuca wyjątek na każdy błąd.

 22
Author: cdunn2001,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-18 19:21:44

Zwykle używampodprocesu razem zshlex (do obsługi ucieczki cytowanych łańcuchów):

>>> import subprocess, shlex
>>> command = 'ls -l "/your/path/with spaces/"'
>>> call_params = shlex.split(command)
>>> print call_params
["ls", "-l", "/your/path/with spaces/"]
>>> subprocess.call(call_params)
 22
Author: Emil Stenström,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-30 14:37:04

Bezwstydny plug, napisałem do tego bibliotekę :P https://github.com/houqp/shell.py

Na razie to w zasadzie opakowanie dla popena i shlexa. Obsługuje również polecenia rurociągów, dzięki czemu można łatwiej łączyć polecenia w Pythonie. Więc możesz robić rzeczy takie jak:
ex('echo hello shell.py') | "awk '{print $2}'"
 17
Author: houqp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-01 20:49:01

W Windows można po prostu zaimportować moduł subprocess i uruchomić zewnętrzne polecenia wywołując subprocess.Popen(), subprocess.Popen().communicate() i subprocess.Popen().wait() Jak poniżej:

# Python script to run a command line
import subprocess

def execute(cmd):
    """
        Purpose  : To execute a command and return exit status
        Argument : cmd - command to execute
        Return   : exit_code
    """
    process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (result, error) = process.communicate()

    rc = process.wait()

    if rc != 0:
        print "Error: failed to execute command:", cmd
        print error
    return result
# def

command = "tasklist | grep python"
print "This process detail: \n", execute(command)

Wyjście:

This process detail:
python.exe                     604 RDP-Tcp#0                  4      5,660 K
 17
Author: Swadhikar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-28 23:08:28

Możesz użyć Popen, a następnie sprawdzić status procedury:

from subprocess import Popen

proc = Popen(['ls', '-l'])
if proc.poll() is None:
    proc.kill()

Sprawdź podproces.Popen .

 16
Author: admire,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-28 23:01:49

Aby pobrać identyfikator sieci z OpenStack Neutron :

#!/usr/bin/python
import os
netid = "nova net-list | awk '/ External / { print $2 }'"
temp = os.popen(netid).read()  /* Here temp also contains new line (\n) */
networkId = temp.rstrip()
print(networkId)

Wyjście nova net-list

+--------------------------------------+------------+------+
| ID                                   | Label      | CIDR |
+--------------------------------------+------------+------+
| 431c9014-5b5d-4b51-a357-66020ffbb123 | test1      | None |
| 27a74fcd-37c0-4789-9414-9531b7e3f126 | External   | None |
| 5a2712e9-70dc-4b0e-9281-17e02f4684c9 | management | None |
| 7aa697f5-0e60-4c15-b4cc-9cb659698512 | Internal   | None |
+--------------------------------------+------------+------+

Wyjście print (networkId)

27a74fcd-37c0-4789-9414-9531b7e3f126
 16
Author: IRSHAD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-29 22:05:32

Pod Linuksem, jeśli chcesz wywołać zewnętrzne polecenie, które będzie działać niezależnie (będzie działać po zakończeniu skryptu Pythona), możesz użyć prostej kolejki jako task spooler lub at

Przykład z task spoolerem:

import os
os.system('ts <your-command>')

Uwagi o task spooler (ts):

  1. Można ustawić liczbę jednoczesnych procesów, które mają być uruchomione ("sloty") za pomocą:

    ts -S <number-of-slots>

  2. Instalowanie ts nie wymaga uprawnień administratora. Możesz pobrać i skompilować go ze źródła za pomocą prostego make, dodać go do swojej ścieżki i gotowe.

 15
Author: Yuval Atzmon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-27 00:15:34