Виклик зовнішньої команди в Python

freshWoWer 08/19/2017. 30 answers, 2.045.096 views
python shell command subprocess external

Як я можу викликати зовнішню команду (начебто я набрала його в командному рядку Unix або в командному рядку Windows) із скрипту Python?

2 Comments
Triton Man 03/19/2015
Гей, ось хороший підручник з інтеграції пітона з оболонкою: dreamsyssoft.com/python-scripting-tutorial/shell-tutorial.ph p
6 J.F. Sebastian 06/12/2015
@TritonMan: це не хороший підручник. Використовуйте for line in proc.stdout: (або for line in iter(proc.stdout.readline, '') у Python 2) замість (moronic) for line in proc.stdout.readlines(): Див. Python: читати потокове введення з subprocess.communicate ()

30 Answers


David Cournapeau 02/14/2017.

Подивіться на модуль підпроцесу в стандартній бібліотеці:

from subprocess import call
call(["ls", "-l"]) 

Перевага subprocess проти system полягає в тому, що вона є більш гнучкою (ви можете отримати stdout, stderr, "реальний" код статусу, краще обробляти помилки тощо ...).

Офіційні документи рекомендують модуль subprocess над альтернативною os.system ():

Модуль subprocess надає більш потужні можливості для створення нових процесів та отримання їх результатів; Використання цього модуля краще використовувати цю функцію [ os.system() ].

У розділі « Заміна застарілих функцій з модулем підпроцесу » у документації subprocess може бути кілька корисних рецептів.

Офіційна документація на модулі subprocess :

5 comments
155 nosklo 05/26/2009
Не можу зрозуміти, чому ви використовуєте os.system навіть для швидкого / брудного / одноразового використання. підпроцесу здається набагато краще.
33 Liam 07/29/2010
Я цілком погоджуюсь з тим, що підпроцесор краще. Я просто повинен був написати швидкий сценарій, подібний до цього, для запуску на старому сервері з Python 2.3.4, який не має модуля підпроцесу.
6 goldenmean 11/10/2013
виклик (..) Отримав мені повідомлення про помилку на oython 2.7.6: Traceback (останній останній виклик): файл "E: \ Ajit \ MyPython \ synonyms1.py", рядок 27, в <module> call ("dir") <br/> Файл "C: \ Python27 \ lib \ subprocess.py", рядок 524, у зворотному дзвінку Popen (* popenargs, ** kwargs) .wait () <br/> Файл "C: \ Python27 \ lib \ subprocess.py ", рядок 711, в init рядку, errwrite) <br/> Файл" C: \ Python27 \ lib \ subprocess.py ", рядок 948, у _execute_child startupinfo) <br/> WindowsError: [Помилка 2] Система не може знайти вказаний файл
61 J.F. Sebastian 12/21/2013
@goldenmean: на мій погляд, у Windows немає ls.exe . Спробуйте call("dir", shell=True)

Eli Courtwright 04/11/2016.

Нижче наведено короткий опис способів виклику зовнішніх програм та переваг та недоліків кожного з них:

  1. os.system("some_command with args") передає команду та аргументи до оболонки вашої системи. Це добре, тому що ви можете одночасно запускати декілька команд таким чином і встановлювати трубки та перенаправлення вводу / виводі. Наприклад:

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

    Проте, якщо це зручно, вам доведеться вручну впоратися зі спамом символів оболонки, наприклад, пробілів тощо. З іншого боку, це також дозволяє запускати команди, які є просто команд оболонки, а не дійсно зовнішніми програмами. Дивіться документацію .

  2. stream = os.popen("some_command with args") буде робити те ж саме, що і os.system за винятком того, що він дає вам файловий об'єкт, який ви можете використовувати для доступу до стандартного вводу / виводу для цього процесу. Існують 3 інших варіанти popen, які всі вказують в / в трохи по-іншому. Якщо ви передаєте все як рядок, то ваша команда передається в оболонку; якщо ви передасте їх як список, то вам не потрібно турбуватися про те, щоб уникнути щось. Дивіться документацію .

  3. Клас subprocess модуля subprocess . Це призначено як заміна для os.popen але має недолік, що становить дещо складніший характер, оскільки є настільки всеосяжним. Наприклад, ви скажете:

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

    замість:

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

    але приємно мати всі варіанти в одному уніфікованому класі замість 4 різних функцій Пена. Дивіться документацію .

  4. Функція call з модуля subprocess . Це в основному так само, як клас Popen і приймає всі ті ж аргументи, але він просто чекає, поки команда завершить і дасть вам код повернення. Наприклад:

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

    Дивіться документацію .

  5. Якщо ви використовуєте Python 3.5 або пізнішої версії, ви можете скористатись новою функцією subprocess.run , яка набагато схожа на наведене вище, але ще більш гнучкою і повертає об'єкт CompletedProcess коли команда завершується виконанням.

  6. Модуль os також має всі функції fork / exec / spawn, які ви мали б у програмі C, але я не рекомендую використовувати їх безпосередньо.

Модуль subprocess ймовірно, повинен бути тим, яким ви користуєтеся.

Насамкінець, будь ласка, майте на увазі, що для всіх методів, де ви передаєте останню команду, яку буде виконувати оболонка як рядок, і ви несете відповідальність за його вичерпання. There are serious security implications якщо будь-яка частина рядка, який ви передаєте, не може бути повністю довіреною. Наприклад, якщо користувач вводить деяку / будь-яку частину рядка. Якщо ви не впевнені, використовуйте ці методи лише за допомогою констант. Щоб дати вам підказку про наслідки розглянути цей код:

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

і уявіть, що користувач входить "моя мама не любить мене && rm-rf /".

5 comments
8 Casebash 05/16/2010
Ви не згадали модуль команд
111 Eli Courtwright 05/16/2010
@Casebash: я не поспішав згадувати це, тому що документація стверджує, що The subprocess module provides more powerful facilities for spawning new processes and retrieving their results. Using the subprocess module is preferable to using the commands module. The subprocess module provides more powerful facilities for spawning new processes and retrieving their results. Using the subprocess module is preferable to using the commands module. Я також не згадав про модуль popen2, оскільки він також застарілий, і він і модулі commands фактично вийшли в Python 3.0 і пізніших. Замість редагування моєї відповіді я дам цей коментар таким чином, як згадуються ці модулі.
15 PhoebeB 11/15/2010
Велика стаття про використання підпроцесу тут: doughellmann.com/PyMOTW/subprocess
11 jldupont 01/21/2012
команди модулів застаріли зараз.
13 simao 06/12/2012
Для багатьох випадків вам не потрібно інстанціувати об'єкт Popen безпосередньо, ви можете використовувати subprocess.check_call і subprocess.check_output

EmmEff 12/10/2016.

Я зазвичай використовую:

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

Ви можете робити те, що ви хочете, за допомогою даних stdout у трубі. Фактично, ви можете просто опустити ці параметри ( stdout= і stderr= ), і він буде вести себе як os.system() .

5 comments
19 J.F. Sebastian 11/16/2012
.readlines() читає all рядки одночасно тобто, він блокується, поки не завершиться підпроцесор (закривається його кінець труби). Для читання в режимі реального часу (якщо немає проблем з буфером) ви можете: for line in iter(p.stdout.readline, ''): print line,
EmmEff 11/17/2012
Не могли б ви розібратися в тому, що ви маєте на увазі під "якщо немає питань буферизації"? Якщо процес певним чином блокується, дзвінок підпроцесу також блокується. Те ж саме може статися і з моїм оригінальним прикладом. Що ще може статися щодо буферизації?
9 J.F. Sebastian 11/17/2012
дочірний процес може використовувати блок-буферизацію в неінтерактивному режимі замість буферизації лінії, тому p.stdout.readline() (примітка: немає в кінці) не побачить жодних даних, поки дитина не заповнить його буфер. Якщо дитина не виробляє багато даних, то виведення не буде в режимі реального часу. Згадайте другу причину в питанні: чому б не просто використовувати трубу (popen ())? . Деякі обхідні шляхи надаються у цьому відповіді (pexpect, pty, stdbuf)
2 J.F. Sebastian 04/10/2013
@Paul: Якщо ваш код створює несподівані результати, ви можете створити повний мінімальний приклад коду, який відтворює проблему та публікує його як нове запитання . Зазначте, що ви очікуєте, і що відбудеться.
2 Paul 04/11/2013
Гаразд взяв вашу пораду stackoverflow.com/questions/15945585/... спасибі!

newtover 07/27/2017.

Деякі натяки на від'єднання дочірнього процесу від викликаючої (початок дитину в фоновому режимі).

Припустімо, ви хочете розпочати довге завдання з CGI-сценарію, тобто дочірний процес повинен тривати довше, ніж процес виконання CGI-сценарію.

Класичний приклад із підпроцесу модуль docs:

import subprocess
import sys

# some code here

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

# some more code here 

Ідея полягає в тому, що ви не хочете чекати в рядку "підпроцеса дзвінка", доки не закінчиться longtask.py. Але незрозуміло, що відбувається після прикладу рядка "ще якийсь код".

Моя цільова платформа була freebsd, але розробка була на вікнах, тому я вперше зіткнувся з проблемою в Windows.

У вікнах (win xp) батьківський процес не закінчиться, поки longtask.py не закінчить свою роботу. Це не те, що ви хочете в CGI-скрипті. Проблема не є специфічною для Python, в спільноті PHP проблеми однакові.

Рішенням є передача прапора DETACHED_PROCESS Process Creation у основну функцію CreateProcess у API win. Якщо вам доведеться встановити pywin32, ви можете імпортувати прапор з модуля win32process, інакше вам слід визначити його самостійно:

DETACHED_PROCESS = 0x00000008

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

/ * UPD 2015.10.27 @eryksun у коментарі нижче зазначає, що семантично правильний прапорець CREATE_NEW_CONSOLE (0x00000010) * /

У freebsd ми маємо ще одну проблему: коли батьківський процес закінчений, він завершує і дочірні процеси. І це не те, що потрібно в CGI-скрипті. Деякі експерименти показали, що проблема, здається, полягає в обміні sys.stdout. І робочим рішенням було:

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

Я не перевірив код на інших платформах і не знаю причин поведінки у freebsd. Якщо хтось знає, поділіться своїми ідеями. Пошук Google при запуску фонових процесів у Python ще не проливає світла.

5 comments
maranas 04/09/2010
дякую за відповідь! Я помітив можливий "примха" при розробці py2exe-додатків в pytet + eclipse. я зміг сказати, що основний скрипт не був відірваний, оскільки вікно виводу Eclipse не закінчилося; навіть якщо скрипт виконує до кінця, він все ще чекає повернення. але коли я намагався компілювати до виконуваного файлу py2exe, відбувається очікувана поведінка (працює процеси як окремі, а потім закривається). Я не впевнений, але виконуване ім'я більше не входить до списку процесів. це працює для всіх підходів (os.system ("start *"), os.spawnl з os.P_DETACH, subprocs і т.д.)
Alexey Lebedev 04/16/2012
Windows gotcha: хоча я породив процес з DETACHED_PROCESS, коли я вбив свій демон Python, всі відкриті ним порти не звільняються, поки всі процеси, що породжуються, не припиняться. WScript.Shell вирішив всі мої проблеми. Приклад тут: pastebin.com/xGmuvwSx
1 J.F. Sebastian 11/16/2012
вам також може знадобитися прапорець CREATE_NEW_PROCESS_GROUP. Дивіться, як Попен чекає на дитину, навіть коли дитина припинив свою роботу
1 eryksun 10/27/2015
Неправильно вказано: "[o] n windows (win xp), батьківський процес не закінчиться, поки longtask.py не завершить роботу". Вихід батька буде нормально, але вікно консолі (консольний екземпляр conhost.exe) закривається лише тоді, коли завершується останній доданий процес, і дитина, можливо, успадкувала консоль батьків. Налаштування DETACHED_PROCESS у DETACHED_PROCESS creationflags запобігає цьому, запобігаючи тому, щоб дитина успадкував або створив консоль. Якщо ви замість цього хочете нову консоль, скористайтеся CREATE_NEW_CONSOLE (0x00000010).
1 eryksun 10/27/2015
Я не мав на увазі, що виконання як окремого процесу є невірним. Тим не менш, вам може знадобитися встановити стандартні ручки для файлів, труб або os.devnull оскільки деякі консольні програми виходять з помилкою в іншому випадку. Створіть нову консоль, коли ви хочете, щоб дочірній процес взаємодіяти з користувачем одночасно з батьківським процесом. Було б незрозуміло спробувати зробити це в одному вікні.

sirwart 04/04/2014.

Я рекомендую використовувати модуль підпроцесора замість os.system, оскільки він вичерпується для вас і, отже, набагато безпечніший: http://docs.python.org/library/subprocess.html

subprocess.call(['ping', 'localhost']) 
2 comments
Joe Skora 09/18/2008
І підпроцесор дозволить вам легко приєднатись до вхідних / вихідних потоків процесу і т. Д.
6 habnabit 09/18/2008
підпроцесія не виконує завдання оболонки для вас, оскільки воно повністю уникає використання оболонки. Це насправді означає, що запуск трохи швидше, а на накладних витратах менше.

Alexandra Franks 01/26/2016.
import os
cmd = 'ls -al'
os.system(cmd) 

Якщо ви хочете повернути результати команди, ви можете використовувати os.popen . Однак, це відхилено з версії 2.6 на користь модуля підпроцесу , які інші відповіді добре покрили.

3 comments
BuvinJ 04/12/2017
Додайте cmd = subprocess.list2cmdline( [ 'my','list','of','tokens' ] ) для обробки викрадень.
Karlos 04/15/2017
Коротка повага до карти локальних ОС при запуску в декількох середовищних системах

nimish 09/18/2008.
import os
os.system("your command") 

Зауважте, що це небезпечно, оскільки команда не очищена. Я залишаю за вами Google для відповідних документів модулів 'os' та 'sys'. Є безліч функцій (exec *, spawn *), які будуть робити подібні речі.


athanassis 05/28/2017.

Перевірте бібліотеку Python "pexpect".

Це дозволяє інтерактивне керування зовнішніми програмами / командами, навіть ssh, ftp, telnet тощо. Ви можете просто набрати щось на зразок:

child = pexpect.spawn('ftp 192.168.0.24')

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

child.sendline('anonymous')

child.expect('(?i)password') 

Jorge E. Cardona 07/23/2013.

Я завжди використовую fabric для таких речей, як:

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

Але це, здається, хороший інструмент: sh (інтерфейс підпроцесу Python) .

Подивіться приклад:

from sh import vgdisplay
print vgdisplay()
print vgdisplay('-v')
print vgdisplay(v=True) 
1 comments
2 Yauhen Yakimovich 05/23/2013
sh перевершує модуль підпроцесу. Це дозволяє краще інтегрувати оболонку

Facundo Casco 12/10/2016.

Якщо вам потрібен вихід із команди, яку ви телефонуєте,
то ви можете використовувати subprocess.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' 

Також зауважте параметр оболонки .

Якщо shell - True , то вказана команда буде виконуватися через оболонку. Це може бути корисно, якщо ви використовуєте Python в першу чергу для посиленого потоку керування, який він пропонує над більшістю системних оболонок, і як і раніше хоче зручний доступ до інших можливостей оболонки, таких як труби оболонки, підменю символів імені файлу, розширення змінної середовища та розширення ~ до дому користувача каталог Однак зауважте, що сам Python пропонує реалізацію багатьох оболонкових функцій (зокрема glob , fnmatch , os.walk() , os.path.expandvars() , os.path.expanduser() , і shutil ).


Usman Khan 10/28/2012.

Ось як я запускаю мої команди. Цей код має все, що вам потрібно

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() 
3 comments
Eric 07/23/2013
Передавання команд як рядків зазвичай є поганою ідеєю
1 Adam Matan 04/02/2014
Я думаю, це прийнятно для команд із жорстким кодуванням, якщо це збільшує читаність.
sam 09/12/2016
Дякую. Коли мова йде про Perl і Ruby, Python є PITA, коли справа доходить до виконання команд. Читайте багато рішень. Подібно твоїм з Попеном.

Honza Javorek 08/12/2016.

З стандартною бібліотекою

Використовуйте модуль підпроцесу :

from subprocess import call
call(['ls', '-l']) 

Це рекомендований стандартний спосіб. Проте складні завдання (труби, вихід, вхід і т. Д.) Можуть бути утомительними для побудови та написання.

Примітка: shlex.split може допомогти вам проаналізувати команду для call та інші функції subprocess якщо ви не хочете (або не можете!) Надавати їх у вигляді списків:

import shlex
from subprocess import call
call(shlex.split('ls -l')) 

З зовнішніми залежностями

Якщо ви не заперечуєте зовнішніх залежностей, використовуйте plumbum :

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

Це найкраща оболонка subprocess . Це крос-платформа, тобто вона працює як на Windows, так і на Unix-подібних системах. Встановити через pip install plumbum .

Інша популярна бібліотека sh :

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

Тим не менш, скинула підтримку Windows, так що це не так здорово, як раніше. Встановити через pip install sh .


Joe 05/23/2017.

Оновлення:

subprocess.run - це рекомендований підхід , подібний до Python 3.5, якщо ваш код не потребує підтримки сумісності з попередніми версіями Python. Це більш послідовний і пропонує аналогічну легкість у використанні як Посланник. (Трубопровід не такий прямий хоча. Дивіться це питання, як це зробити .)

Ось кілька прикладів з документів .

Запустіть процес:

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

Підняти на невдалому ході:

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

Захоплення виходу:

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

Оригінальна відповідь:

Я рекомендую спробувати Посланника . Це обгортка для підпроцесу, яка в свою чергу покликана замінити старі модулі та функції. Посланник є підпроцесою для людини.

Приклад використання з 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
'' 

Також матеріал для труб:

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

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

>>> r.history
[] 
2 comments
4 J.F. Sebastian 10/03/2015
Примітка: subprocess.run() яка ігнорує ненульовий статус завершення за замовчуванням, є регресом у порівнянні з subprocess.check_call() або subprocess.check_output() . python -mthis : "Помилки ніколи не повинні проходити мовчки, якщо вони явно не затьмарені".
itirazimvar 09/01/2016
Спасибі, людина посланник працює краще, ніж підпроцес, Ти врятував свій день. Команда команда = "ansible-playbook playbook.yaml --extra-vars = \" esxi_host = {0} extravar1 = {1} extravar2 = {2} extravar3 = {3} \ "". Формат (extravar1, extravar2 , extravar3) і r.envoy.run (команда)

Tom Fuller 05/28/2017.

Є багато різних бібліотек, які дозволяють викликати зовнішні команди за допомогою Python. Для кожної бібліотеки я надав опис і показав приклад виклику зовнішньої команди. Наприклад, команда ls -l (список усіх файлів). Якщо ви хочете дізнатись більше про будь-яку зі згаданих бібліотек і пов'язати документацію для кожного з них.

Sources:

These are all the libraries:

Сподіваємося, це допоможе вам прийняти рішення щодо використання бібліотеки :)

subprocess

Підпроцесс дозволяє викликати зовнішні команди та підключати їх до труб вводу / виводу / помилок (stdin, stdout та stderr). Підпроцесор є вибір за замовчуванням для запуску команд, але іноді інші модулі краще.

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

OS використовується для "функціональних можливостей операційної системи". Він також може використовуватися для виклику зовнішніх команд за допомогою os.system та os.popen (Примітка: існує також subprocess.popen). OS завжди буде запускати оболонку, і це проста альтернатива для людей, яким не потрібно, або не знаю, як використовувати subprocess.run .

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

sh

sh - це підпроцесорний інтерфейс, який дозволяє вам викликати програми так, якби вони були функціями. Це корисно, якщо ви бажаєте запустити команду кілька разів.

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 - це бібліотека для програм "Python", подібних до сценаріїв. Ви можете викликати програми, подібні до функцій, як у sh . Plumbum корисний, якщо ви хочете запустити трубопровід без оболонки.

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

pexpect

pexpect дозволяє вам створювати дитячі програми, керувати ними та знаходити закономірності їхнього випуску. Це краща альтернатива підпроцесу для команд, які очікують tty на Unix.

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

fabric

тканина - бібліотека Python 2.5 та 2.7. Це дозволяє виконувати локальні та віддалені команди оболонки. Тканина є простою альтернативою для запуску команд у захищеній оболонці (SSH)

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

envoy

Посланник відомий як "підпроцесор для людини". Він використовується як зручна оболонка навколо модуля subprocess .

r = envoy.run("ls -l") # Run command
r.std_out # get output 

commands

commands містять функції обгортки для os.popen , але вони були вилучені з Python 3, оскільки subprocess є кращою альтернативою.

Редаговано на основі коментаря Дж. Ф. Себастьяна.

4 comments
Tom Fuller 10/29/2016
Я пропустив будь-який?
3 J.F. Sebastian 11/02/2016
Можливо, було б корисно ясно вказати, when і why ви б віддавали перевагу одній бібліотеці над іншим, наприклад, pexpect корисний для команд, які очікують tty на Unix , plumbum може бути використаний для запуску конвеєра без запуску оболонки , fabric є простим способом запускати команди через ssh, subprocess (на відміну від os ) ніколи не запускає оболонку, якщо ви не запитуєте - це вибір за замовчуванням для запуску зовнішніх команд, іноді вам можуть знадобитися альтернативи .
Tom Fuller 11/02/2016
Я відредагував мою відповідь на основі ваших відгуків :)
1 J.F. Sebastian 11/02/2016
os "зовнішні команди" виконуються з точки зору subprocess внутрішньо. Це може бути корисним для людей з інших мов ( system() , popen() є загальним API), які не потребують повної потужності модуля subprocess та не мають часу, щоб дізнатися, як використовувати subprocess.run() та інша функція підпроцесу.

Zuckonit 05/28/2017.

Без вихідного результату:

import os
os.system("your command here") 

З виходом результату:

import commands
commands.getoutput("your command here")
or
commands.getstatusoutput("your command here") 
1 comments
2 Ramsharan 10/19/2013
Мені подобається частина with output of result . Мені це було потрібно для використання в чудовій консолі.

stuckintheshuck 10/10/2014.

Існує також Plumbum

>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand()
>>> 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 
1 comments
J.F. Sebastian 07/13/2015
або додати трохи магії: from plumbum.cmd import ls, grep; output = (ls | grep['pattern'])() from plumbum.cmd import ls, grep; output = (ls | grep['pattern'])()

Ben Hoffstein 11/02/2014.

https://docs.python.org/2/library/subprocess.html

... або для дуже простої команди:

import os
os.system('cat testfile') 

Martin W 12/10/2016.

os.system це нормально, але тип датований. Це також не дуже безпечно. Замість цього спробуйте subprocess . subprocess не викликає безпосередньо sh і тому є більш безпечним, ніж os.system .

Отримати більше інформації тут .


William Keller 12/10/2016.

os.system замінено модулем subprocess . Використовуйте замість підпроцесу.

3 comments
14 Michael Mior 03/29/2010
Може бути, приклад використання subprocess ?
5 Mark Amery 12/22/2016
Враховуючи, що прийнята відповідь запропонувала subprocess раніше і більш детально, я не бачу ніякої цінності для відповіді на цю відповідь.
sudo 04/23/2017
Що трапилось з os.system ? Це самий інтуїтивно зрозумілий, просто запускає те, що ви вкладаєте в рядок, і не маєте всіх застережень, які люди містять під прийнятною відповіддю.

cdunn2001 01/18/2011.

subprocess.check_call зручно, якщо ви не хочете перевіряти повернення значень. Це видає виняток з будь-якої помилки.


Atinc Delican 12/10/2016.

Існує ще одна різниця тут, що не згадується вище.

subprocess.Popen виконує як підпроцес. У моєму випадку мені потрібно виконати файл, який потрібно зв'язати з іншою програмою.

Я спробував підпроцес, виконання було успішним. Однак не могла комм. /. все нормально, коли я запускаю обидва з терміналу.

Ще один: (ПРИМІТКА: kwrite веде себе відрізняється від інших додатків. Якщо спробувати нижче, результати Firefox не будуть однаковими)

Якщо ви спробуєте os.system("kwrite") , потік програми зависає, поки користувач не закриває kwrite. Щоб подолати те, я спробував замість цього os.system(konsole -e kwrite) . Цього разу програма продовжувала текти, але kwrite стала підпроцесою консолі.

Будь-хто запускає kwrite, що не є підпроцесою (тобто на системному моніторі він повинен з'явитися на лівому краю дерева)


Priyankara 05/28/2017.

Використання:

import os

cmd = 'ls -al'

os.system(cmd) 

OS - Цей модуль забезпечує портативний спосіб використання функціональних можливостей операційної системи.

Для додаткових функцій, ось документація.

3 comments
PolarisUser 10/09/2015
Чи є спосіб натиснути результат cmd на файл? Я скручую веб-сайт і хочу, щоб він перейшов у файл.
user2820579 10/16/2015
Це, безумовно, найпростіше і потужне рішення. @PolarisUser ви можете скористатись загальною командою linux: > outputfile.txt
Corey Goldberg 12/09/2015
це також погано. використовувати підпроцесу

Saurabh Bangad 06/11/2012.

os.system не дозволяє зберігати результати, так що якщо ви хочете зберегти результати в деякому списку або щось, то працює subprocess.call .


Emil Stenström 04/30/2014.

Я, як правило, використовую підпроцесор разом з shlex (для обробки випалу цитаткових рядків):

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

houqp 05/01/2014.

Безжальний роз'єм, я створив бібліотеку для цього: P https://github.com/houqp/shell.py

Це в основному обгортка для попена і шлексу на даний момент. Вона також підтримує команди для керування трубопроводами, таким чином, ви можете спростити ланцюг команд у Python. Отже, ви можете робити такі речі, як:

ex('echo hello shell.py') | "awk '{print $2}'" 

admire 05/28/2017.

Ви можете використовувати Popen, а потім ви можете перевірити стан процедури:

from subprocess import Popen

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

Перевірте підпроцес .


IRSHAD 07/20/2016.

Щоб отримати ідентифікатор мережі з відкритого важеля нейтрона:

#!/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) 

Вихід 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 |
+--------------------------------------+------------+------+ 

Вихід print(networkId)

27a74fcd-37c0-4789-9414-9531b7e3f126 

yuval 11/27/2016.

Під Linux, у випадку, якщо ви хочете викликати зовнішню команду, яка буде виконуватися незалежно (продовжуватиме працювати після закінчення скрипту python), ви можете використовувати просту чергу як спулер завдання або команду

Приклад із спулером завдань:

import os
os.system('ts ') 

Примітки про завдання спулера ( ts ):

  1. Ви можете встановити кількість одночасних процесів, які будуть запущені ("слоти") з:

    ts -S

  2. Встановлення ts не вимагає прав адміністратора. Ви можете завантажити та скомпілювати його з джерела за допомогою простого make , додати його на свій шлях, і ти все закінчиш.


urosjarc 05/28/2017.

Ось мої два центи: на мій погляд, це найкраща практика при роботі з зовнішніми командами ...

Це зворотні значення методу виконання ...

pass, stdout, stderr = execute(["ls","-la"],"/home/user/desktop") 

Це метод виконання ...

def execute(cmdArray,workingDir):

    stdout = ''
    stderr = ''

    try:
        try:
            process = subprocess.Popen(cmdArray,cwd=workingDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1)
        except OSError:
            return [False, '', 'ERROR : command(' + ' '.join(cmdArray) + ') could not get executed!']

        for line in iter(process.stdout.readline, b''):

            try:
                echoLine = line.decode("utf-8")
            except:
                echoLine = str(line)

            stdout += echoLine

        for line in iter(process.stderr.readline, b''):

            try:
                echoLine = line.decode("utf-8")
            except:
                echoLine = str(line)

            stderr += echoLine

    except (KeyboardInterrupt,SystemExit) as err:
        return [False,'',str(err)]

    process.stdout.close()

    returnCode = process.wait()
    if returnCode != 0 or stderr != '':
        return [False, stdout, stderr]
    else:
        return [True, stdout, stderr] 
1 comments
ppperry 07/07/2016
Потенціал для .communicate замість цього використовуйте метод .communicate

Swadhikar C 05/28/2017.

У Windows ви можете просто імпортувати модуль subprocess та запускати зовнішні команди, викликаючи subprocess.Popen() , subprocess.Popen().communicate() і subprocess.Popen().wait() як показано нижче:

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

Вихід:

This process detail:
python.exe                     604 RDP-Tcp#0                  4      5,660 K 

Related questions

Hot questions

Language

Popular Tags