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

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

Ответы [ 56 ]

13 голосов
/ 16 июля 2012

Вы можете использовать Popen, а затем вы можете проверить статус процедуры:

from subprocess import Popen

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

Проверить подпроцесс. Открыть .

12 голосов
/ 25 июля 2012

Очень простой способ выполнить любую команду и получить результат обратно:

from commands import getstatusoutput

try:
    return getstatusoutput("ls -ltr")
except Exception, e:
    return None
12 голосов
/ 15 сентября 2018

Invoke - это инструмент и библиотека для выполнения задач Python (2.7 и 3.4+). Он обеспечивает чистый API высокого уровня для запуска команд оболочки

>>> from invoke import run
>>> cmd = "pip install -r requirements.txt"
>>> result = run(cmd, hide=True, warn=True)
>>> print(result.ok)
True
>>> print(result.stdout.splitlines()[-1])
Successfully installed invocations-0.13.0 pep8-1.5.7 spec-1.3.1
11 голосов
/ 14 октября 2015

Вот мои два цента: На мой взгляд, это лучший способ работы с внешними командами ...

Это возвращаемые значения из метода execute ...

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]
11 голосов
/ 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)

Вывод net-list * nova

+--------------------------------------+------------+------+
| 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
8 голосов
/ 23 марта 2018

Часто я использую следующую функцию для внешних команд, и это особенно удобно для длительных процессов . Приведенный ниже метод завершает вывод процесса , пока работает и возвращает вывод, вызывает исключение в случае сбоя процесса.

Выдается, если процесс выполняется с использованием метода poll () для процесса .

import subprocess,sys

def exec_long_running_proc(command, args):
    cmd = "{} {}".format(command, " ".join(str(arg) if ' ' not in arg else arg.replace(' ','\ ') for arg in args))
    print(cmd)
    process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    # Poll process for new output until finished
    while True:
        nextline = process.stdout.readline().decode('UTF-8')
        if nextline == '' and process.poll() is not None:
            break
        sys.stdout.write(nextline)
        sys.stdout.flush()

    output = process.communicate()[0]
    exitCode = process.returncode

    if (exitCode == 0):
        return output
    else:
        raise Exception(command, exitCode, output)

Вы можете вызвать его так:

exec_long_running_proc(command = "hive", args=["-f", hql_path])
7 голосов
/ 04 апреля 2018

Вызов внешней команды в Python

Простой способ вызова внешней команды - использование os.system(...). И эта функция возвращает значение выхода команды. Но недостаток в том, что мы не получим stdout и stderr.

ret = os.system('some_cmd.sh')
if ret != 0 :
    print 'some_cmd.sh execution returned failure'

Вызов внешней команды в Python в фоновом режиме

subprocess.Popen обеспечивает большую гибкость для запуска внешней команды вместо использования os.system. Мы можем запустить команду в фоновом режиме и дождаться ее завершения. И после этого мы можем получить stdout и stderr.

proc = subprocess.Popen(["./some_cmd.sh"], stdout=subprocess.PIPE)
print 'waiting for ' + str(proc.pid)
proc.wait()
print 'some_cmd.sh execution finished'
(out, err) = proc.communicate()
print 'some_cmd.sh output : ' + out

Вызов длительной внешней команды в Python в фоновом режиме и остановка через некоторое время

Мы даже можем запустить длительный процесс в фоновом режиме, используя subprocess.Popen, и убить его через некоторое время после выполнения задачи.

proc = subprocess.Popen(["./some_long_run_cmd.sh"], stdout=subprocess.PIPE)
# Do something else
# Now some_long_run_cmd.sh exeuction is no longer needed, so kill it
os.system('kill -15 ' + str(proc.pid))
print 'Output : ' proc.communicate()[0]
7 голосов
/ 11 октября 2016

Здесь вызывается внешняя команда и возвращается или выводится вывод команды:

Python Подпроцесс check_output подходит для

Запустить команду с аргументами и вернуть ее вывод в виде байтовой строки.

import subprocess
proc = subprocess.check_output('ipconfig /all')
print proc
7 голосов
/ 31 января 2018

Как пример (в Linux):

import subprocess
subprocess.run('mkdir test.dir', shell=True)

Это создает test.dir в текущем каталоге. Обратите внимание, что это также работает:

import subprocess
subprocess.call('mkdir test.dir', shell=True)

Эквивалентный код с использованием os.system:

import os
os.system('mkdir test.dir')

Лучше всего использовать подпроцесс вместо os, при этом .run предпочтительнее, чем .call Все, что вам нужно знать о подпроцессе, это здесь . Также обратите внимание, что всю документацию по Python можно загрузить с здесь . Я скачал PDF, упакованный как .zip. Я упоминаю об этом, потому что есть хороший обзор модуля os в tutorial.pdf (стр. 81). Кроме того, это авторитетный ресурс для программистов Python.

7 голосов
/ 05 февраля 2019

Существует два основных способа выполнения команд оболочки с использованием Python. Оба приведенных ниже примера показывают, как можно получить имя текущего рабочего каталога (pwd), используя Python. Вы можете использовать любую другую команду Unix вместо pwd.

1.> 1-й метод: Можно использовать модуль os из python и функцию system () оттуда для выполнения команд оболочки в Python.

import os
os.system('pwd')

Выход:

/Users/siddharth

1.> 2-й метод: Другой способ - использовать модуль подпроцесс и функцию call () .

import subprocess
subprocess.call('pwd')

Выход:

/Users/siddharth
...