Вызов внешней команды в Python - PullRequest
4261 голосов
/ 18 сентября 2008

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

Ответы [ 56 ]

7 голосов
/ 20 июня 2013

Просто чтобы добавить к обсуждению, если вы используете консоль Python, вы можете вызывать внешние команды из IPython . Находясь в приглашении IPython, вы можете вызывать команды оболочки, используя префикс «!». Вы также можете комбинировать код Python с оболочкой и назначать вывод сценариев оболочки переменным Python.

Например:

In [9]: mylist = !ls

In [10]: mylist
Out[10]:
['file1',
 'file2',
 'file3',]
7 голосов
/ 24 июня 2016

Использование:

import subprocess

p = subprocess.Popen("df -h", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
print p.split("\n")

Это дает хороший вывод, с которым легче работать:

['Filesystem      Size  Used Avail Use% Mounted on',
 '/dev/sda6        32G   21G   11G  67% /',
 'none            4.0K     0  4.0K   0% /sys/fs/cgroup',
 'udev            1.9G  4.0K  1.9G   1% /dev',
 'tmpfs           387M  1.4M  386M   1% /run',
 'none            5.0M     0  5.0M   0% /run/lock',
 'none            1.9G   58M  1.9G   3% /run/shm',
 'none            100M   32K  100M   1% /run/user',
 '/dev/sda5       340G  222G  100G  69% /home',
 '']
6 голосов
/ 17 апреля 2013

Есть много разных способов запуска внешних команд в Python, и все они имеют свои плюсы и минусы.

Мои коллеги и я пишем инструменты системного администрирования Python, поэтому нам нужно запускать множество внешних команд, а иногда вы хотите, чтобы они блокировались или выполнялись асинхронно, по таймауту, обновлялись каждую секунду и т. Д.

Существуют также разные способы обработки кода возврата и ошибок, и, возможно, вы захотите проанализировать вывод и предоставить новый ввод (в стиле ожидайте ). Или вам нужно будет перенаправить stdin, stdout и stderr для запуска в другом tty (например, при использовании screen).

Так что вам, вероятно, придется написать много оберток вокруг внешней команды. Итак, вот модуль Python, который мы написали, который может обрабатывать почти все, что вы хотели бы, и если нет, то оно очень гибкое, так что вы можете легко расширить его:

https://github.com/hpcugent/vsc-base/blob/master/lib/vsc/utils/run.py

5 голосов
/ 08 мая 2018

Если вам нужно вызвать команду оболочки из записной книжки Python (например, Jupyter , Zeppelin, Databricks или Google Cloud Datalab), вы можете просто использовать префикс !.

Например,

!ls -ilF
5 голосов
/ 17 марта 2016

Для Python 3.5+ рекомендуется использовать функцию запуска из модуля подпроцесса . Это возвращает объект CompletedProcess, из которого вы можете легко получить выходные данные и код возврата.

from subprocess import PIPE, run

command = ['echo', 'hello']
result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
print(result.returncode, result.stdout, result.stderr)
4 голосов
/ 25 августа 2014

Простой способ - использовать модуль os:

import os
os.system('ls')

В качестве альтернативы вы также можете использовать модуль подпроцесса

import subprocess
subprocess.check_call('ls')

Если вы хотите, чтобы результат был сохранен в переменной, попробуйте:

import subprocess
r = subprocess.check_output('ls')
4 голосов
/ 12 сентября 2016

Существует много способов вызова команды.

  • Например:

, если and.exe нужны два параметра. В cmd мы можем вызвать sample.exe и использовать это: and.exe 2 3 и на экране отображается 5.

Если мы используем сценарий Python для вызова and.exe, мы должны сделать так:

  1. os.system(cmd,...)

    • os.system(("and.exe" + " " + "2" + " " + "3"))
  2. os.popen(cmd,...)

    • os.popen(("and.exe" + " " + "2" + " " + "3"))
  3. subprocess.Popen(cmd,...)
    • subprocess.Popen(("and.exe" + " " + "2" + " " + "3"))

Это слишком сложно, поэтому мы можем объединить cmd с пробелом:

import os
cmd = " ".join(exename,parameters)
os.popen(cmd)
4 голосов
/ 24 июля 2015

Использование функции Popen модуля subprocess Python - это самый простой способ запуска команд Linux. При этом функция Popen.communicate() выдаст ваши команды на вывод. Например

import subprocess

..
process = subprocess.Popen(..)   # Pass command and arguments to the function
stdout, stderr = process.communicate()   # Get command output and error
..
4 голосов
/ 12 апреля 2014

Использовать subprocess.call :

from subprocess import call

# using list
call(["echo", "Hello", "world"])

# single string argument varies across platforms so better split it
call("echo Hello world".split(" "))
4 голосов
/ 30 октября 2018

Я написал небольшую библиотеку, чтобы помочь с этим вариантом использования:

https://pypi.org/project/citizenshell/

Может быть установлен с помощью

pip install citizenshell

А затем используется следующим образом:

from citizenshell import sh
assert sh("echo Hello World") == "Hello World"

Вы можете отделить стандартный вывод от stderr и извлечь код выхода следующим образом:

result = sh(">&2 echo error && echo output && exit 13")
assert result.stdout() == ["output"]
assert result.stderr() == ["error"]
assert result.exit_code() == 13

И самое интересное в том, что вам не нужно ждать выхода из базовой оболочки, прежде чем начинать обрабатывать вывод:

for line in sh("for i in 1 2 3 4; do echo -n 'It is '; date +%H:%M:%S; sleep 1; done", wait=False)
    print ">>>", line + "!"

будет печатать строки по мере их появления благодаря ожиданию = False

>>> It is 14:24:52!
>>> It is 14:24:53!
>>> It is 14:24:54!
>>> It is 14:24:55!

Дополнительные примеры можно найти на https://github.com/meuter/citizenshell

...