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

4003

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

Теги:
external
subprocess
command

56 ответов

4030
Лучший ответ

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

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

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

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

Модуль подпроцесса предоставляет более мощные средства для порождения новых процессов и получения их результатов; использование этого модуля предпочтительнее, чем использование этой функции [ os.system() ].

Раздел " Замена старых функций модулем подпроцесса " в документации подпроцесса может иметь несколько полезных рецептов.

  • 0
    Есть ли способ использовать подстановку переменных? IE я попытался сделать echo $PATH с помощью call(["echo", "$PATH"]) , но он просто повторил буквальную строку $PATH вместо какой-либо замены. Я знаю, что могу получить переменную среды PATH, но мне интересно, есть ли простой способ заставить команду вести себя точно так же, как если бы я выполнял ее в bash.
  • 0
    @KevinWheeler Вы должны будете использовать shell=True , чтобы это работало.
Показать ещё 14 комментариев
2509

Здесь приведено краткое описание способов вызова внешних программ и преимуществ и недостатков каждого из них:

  • os.system("some_command with args") передает команду и аргументы вашей системной оболочке. Это хорошо, потому что вы можете запускать сразу несколько команд таким образом и настраивать каналы и перенаправление ввода/вывода. Например:

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

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

  • stream = os.popen("some_command with args") будет делать то же самое, что и os.system, за исключением того, что он дает вам файл-подобный объект, который вы можете использовать для доступа к стандартным вводам/выводам для этого процесса. Есть еще 3 варианта popen, которые все обрабатывают i/o немного по-другому. Если вы передаете все как строку, ваша команда передается в оболочку; если вы передадите их в список, то вам не нужно беспокоиться о том, чтобы избежать чего-либо. Смотрите документацию.

  • Класс Popen модуля subprocess. Это предназначено для замены os.popen, но имеет недостаток в том, что он немного усложняется благодаря тому, что он является настолько всеобъемлющим. Например, вы бы сказали:

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

    вместо:

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

    но хорошо иметь все варианты там в одном унифицированном классе вместо 4 разных функций popen. См. документацию.

  • Функция call из модуля subprocess. Это в основном так же, как класс Popen, и принимает все те же аргументы, но он просто ждет, пока команда не завершится, и вы получите код возврата. Например:

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

    Смотрите документацию.

  • Если вы используете Python 3.5 или более позднюю версию, вы можете использовать новую функцию subprocess.run, что очень похоже на выше, но еще более гибкой и возвращает объект CompletedProcess, когда команда завершает выполнение.

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

Модуль subprocess должен, вероятно, быть тем, что вы используете.

Наконец, имейте в виду, что для всех методов, в которых вы передаете окончательную команду, которая будет выполняться оболочкой в ​​виде строки, и вы несете ответственность за ее удаление. Существуют серьезные последствия для безопасности, если какая-либо часть передаваемой строки не может быть полностью доверена. Например, если пользователь вводит какую-либо/любую часть строки. Если вы не уверены, используйте эти методы только с константами. Чтобы дать вам намек на последствия, рассмотрите этот код:

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

и представьте, что пользователь вводит "моя мама не любила меня && rm -rf/".

  • 9
    Хороший ответ / объяснение. Как этот ответ оправдывает девиз Python, описанный в этой статье? fastcompany.com/3026446/… «Стилистически, Perl и Python имеют разные философии. Самый известный девиз Perl:« Есть больше, чем один способ сделать это ». Python разработан так, чтобы иметь один очевидный способ сделать это» Кажется, так и должно быть другой способ! В Perl я знаю только два способа выполнить команду - с помощью back-tick или open .
  • 7
    Если вы используете Python 3.5+, используйте subprocess.run() . docs.python.org/3.5/library/subprocess.html#subprocess.run
Показать ещё 6 комментариев
290

Я обычно использую:

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

  • 34
    .readlines() читает все строки сразу, т.е. блокируется до выхода из подпроцесса (закрывает свой конец канала). Для чтения в режиме реального времени (если нет проблем с буферизацией) вы можете: for line in iter(p.stdout.readline, ''): print line,
  • 1
    Не могли бы вы уточнить, что вы подразумеваете под «если нет проблем с буферизацией»? Если процесс блокируется определенным образом, вызов подпроцесса также блокируется. То же самое может случиться и с моим оригинальным примером. Что еще может произойти в отношении буферизации?
Показать ещё 3 комментария
182

Некоторые подсказки по отсоединению дочернего процесса от вызывающего (запуск дочернего процесса в фоновом режиме).

Предположим, вы хотите запустить длинную задачу из CGI- script, то есть дочерний процесс должен жить дольше, чем процесс выполнения CGI- script.

Классический пример из документов модуля подпроцесса:

import subprocess
import sys

# some code here

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

# some more code here

Идея здесь заключается в том, что вы не хотите ждать в подпроцессе "call sub" до тех пор, пока longtask.py не будет завершен. Но неясно, что происходит после строки "еще один код здесь" из примера.

Моя целевая платформа была бесплатной, но разработка была в Windows, поэтому я сначала столкнулся с проблемой в Windows.

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

Решение состоит в том, чтобы передать DETACHED_PROCESS флаг создания процесса в базовую функцию CreateProcess в win API. Если вы установили 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- script. Некоторые эксперименты показали, что проблема, по-видимому, заключается в совместном использовании sys.stdout. И рабочим решением было следующее:

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

Я не проверял код на других платформах и не знаю причин поведения на freebsd. Если кто-нибудь знает, пожалуйста, поделитесь своими идеями. Googling при запуске фоновых процессов в Python еще не проливает свет.

  • 0
    я заметил возможную «причуду» разработки приложений py2exe в pydev + eclipse. я был в состоянии сказать, что основной скрипт не был отсоединен, потому что окно вывода eclipse не заканчивалось; даже если скрипт выполняется до конца, он все еще ожидает возврата. но, когда я попытался скомпилировать в исполняемый файл py2exe, происходит ожидаемое поведение (запускает процессы как отдельные, а затем завершает работу). Я не уверен, но имя исполняемого файла больше нет в списке процессов. это работает для всех подходов (os.system ("start *"), os.spawnl с os.P_DETACH, подпрограммы и т. д.)
  • 0
    Понятно, что Windows: несмотря на то, что я порождал процесс с помощью DETACHED_PROCESS, когда я убивал своего демона Python, все открытые им порты не освобождались до тех пор, пока все порожденные процессы не завершатся. WScript.Shell решил все мои проблемы. Пример здесь: pastebin.com/xGmuvwSx
Показать ещё 10 комментариев
115
import os
cmd = 'ls -al'
os.system(cmd)

Если вы хотите вернуть результаты команды, вы можете использовать os.popen. Тем не менее, это устарело со версии 2.6 в пользу модуля подпроцесса, который другие ответы хорошо рассмотрели.

  • 6
    popen устарела в пользу подпроцесса .
  • 0
    Вы также можете сохранить результат с помощью вызова os.system, так как он работает как сама оболочка UNIX, например, os.system ('ls -l> test2.txt')
113

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

subprocess.call(['ping', 'localhost'])
  • 0
    Если вы хотите создать список из команды с параметрами , список, который можно использовать с subprocess когда shell=False , тогда используйте shlex.split для простого способа сделать это docs.python.org/2/library/shlex .html # shlex.split (это рекомендуемый способ в соответствии с docs docs.python.org/2/library/subprocess.html#popen-constructor )
  • 3
    Это неверно: « он спасает вас от оболочки и поэтому намного безопаснее ». подпроцесс не выполняет экранирование оболочки, субпроцесс не передает вашу команду через оболочку, поэтому нет необходимости экранировать оболочку.
97
import os
os.system("your command")

Обратите внимание, что это опасно, так как команда не очищается. Я оставляю это для вас в google для соответствующей документации по модулям "os" и "sys". Есть куча функций (exec * и spawn *), которые будут делать подобные вещи.

  • 0
    Что вы подразумеваете под "команда не очищена" ?
  • 4
    Понятия не имею, что я имел в виду почти десять лет назад (проверьте дату!), Но если бы мне пришлось угадывать, было бы, что проверка не была сделана.
Показать ещё 2 комментария
64

Существует множество разных библиотек, которые позволяют вам вызывать внешние команды с помощью Python. Для каждой библиотеки я дал описание и показал пример вызова внешней команды. В качестве примера я использовал команду ls -l (список всех файлов). Если вы хотите узнать больше о любой из библиотек, которые я перечислил, и связать документацию для каждого из них.

Источники:

  

Это все библиотеки:

  

Надеюсь, это поможет вам принять решение о том, какую библиотеку использовать:)

подпроцесс

Подпроцесс позволяет вам вызывать внешние команды и подключать их к их каналам ввода/вывода/ошибок (stdin, stdout и stderr). Subprocess - это выбор по умолчанию для запуска команд, но иногда другие модули лучше.

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.system и os.popen (Примечание: существует также подпроцесс .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.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 - это библиотека для "script -подобных" программ 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 [email protected]:.') # 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 содержит функции-обертки для os.popen, но он был удален из Python 3, поскольку subprocess является лучшей альтернативой.

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

59

Я всегда использую 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)
58

Также проверьте библиотеку Python "pexpect".

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

child = pexpect.spawn('ftp 192.168.0.24')

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

child.sendline('anonymous')

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

Если вам нужен вывод из команды, которую вы вызываете, вы можете использовать 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).

  • 1
    Обратите внимание, что check_output требует список, а не строку. Если вы не полагаетесь на пробелы в кавычках, чтобы сделать ваш вызов действительным, самый простой и читаемый способ сделать это - subprocess.check_output("ls -l /dev/null".split()) .
46

Со стандартной библиотекой

Модуль подпроцесса использования (Python 3):

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

Это рекомендуемый стандартный способ. Однако более сложные задачи (трубы, выходные данные, ввод и т.д.) Могут быть утомительными для создания и записи.

Примечание по версии Python: если вы все еще используете Python 2, subprocess.call работает аналогичным образом.

ProTip: shlex.split может помочь вам разобрать команду для run, call и других функций subprocess в случае, если вы не хотите (или не можете!) Предоставить их в виде списков:

import shlex
import subprocess
subprocess.run(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'))

Тем не менее sh отказался от поддержки Windows, поэтому он не такой потрясающий, как раньше. Устанавливать по pip install sh.

42

Вот как я запускаю свои команды. Этот код содержит все, что вам нужно.

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()
  • 2
    Передача команд в виде строк, как правило, плохая идея
  • 2
    Я думаю, что это приемлемо для жестко запрограммированных команд, если это повышает удобочитаемость.
39

Update:

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

Оригинальный ответ:

Я рекомендую попробовать Envoy. Это оболочка для подпроцесса, которая, в свою очередь, старается заменить более старые модули и функции. Посланник является подпроцессом для людей.

Пример использования 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
[<Response 'uptime'>]
32

Без вывода результата:

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

С выходом результата:

import commands
commands.getoutput("your command here")
or
commands.getstatusoutput("your command here")
  • 0
    commands больше не доступны в Python 3. Вы должны предпочесть subprocess os.system()
27

Существует также 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
26

os.system ОК, но вроде датировано. Это также не очень безопасно. Вместо этого попробуйте subprocess. subprocess не вызывает sh напрямую и поэтому более безопасен, чем os.system.

Получить дополнительную информацию здесь.

  • 1
    Хотя я согласен с общей рекомендацией, subprocess не устраняет все проблемы с безопасностью и имеет свои собственные неприятные проблемы.
26

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

... или для очень простой команды:

import os
os.system('cat testfile')
25

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

Простой, используйте subprocess.run, который возвращает объект CompletedProcess:

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

Почему?

Как и в Python 3.5, в документации рекомендуется subprocess.run:

Рекомендуемым подходом к вызову подпроцессов является использование функции run() для всех случаев использования, которые она может обрабатывать. Для более продвинутых случаев использования интерфейс Popen можно использовать напрямую.

Вот пример простейшего возможного использования - и он точно так же спрашивает:

>>> 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 ждет завершения команды, а затем возвращает объект CompletedProcess. Он может вместо этого поднимать TimeoutExpired (если вы даете ему аргумент timeout=) или CalledProcessError (если он терпит неудачу и вы проходите check=True).

Как вы могли бы сделать вывод из приведенного выше примера, stdout и stderr оба по умолчанию передаются на ваш собственный stdout и stderr.

Мы можем проверить возвращаемый объект и увидеть команду, которая была указана, и код возврата:

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

Захват вывода

Если вы хотите захватить вывод, вы можете передать subprocess.PIPE в соответствующие stderr или 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''

(Я нахожу это интересным и слегка противоречивым, что информация о версии попадает в stderr вместо stdout.)

Передайте список команд

Можно легко перейти от ручного предоставления командной строки (например, вопрос) к созданию строки, построенной программно. Не программировать строки программно. Это потенциальная проблема безопасности. Лучше предположить, что вы не доверяете входным данным.

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

Обратите внимание, что только args следует передавать позиционно.

Полная подпись

Здесь действительная подпись в источнике и как показано help(run):

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

popenargs и kwargs присваиваются конструктору Popen. input может быть строкой байтов (или unicode, если указать кодировку или universal_newlines=True), которые будут переданы в подпроцесс stdin.

Документация описывает timeout= и check=True лучше, чем я мог:

Аргумент timeout передается в Popen.communicate(). Если тайм-аут истекает, дочерний процесс будет убит и ждет. Исключение TimeoutExpired будет повторно поднято после того, как дочерний процесс будет прекращается.

Если проверка верна, и процесс завершается с ненулевым кодом выхода, Вызов CalledProcessError будет повышен. Атрибуты этого исключение содержат аргументы, код выхода и stdout и stderr, если они были захвачены.

и этот пример для check=True лучше, чем один, который я мог бы придумать:

>>> 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(args, *, stdin=None, input=None, stdout=None, stderr=None, 
shell=False, cwd=None, timeout=None, check=False, encoding=None, 
errors=None)

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

Popen

При использовании Popen вместо этого? Я бы изо всех сил пытался найти прецедент, основанный только на аргументах. Однако прямое использование Popen даст вам доступ к его методам, включая poll, 'send_signal', 'terminate' и 'wait'.

Здесь подпись Popen, указанная в источнике. Я думаю, что это наиболее точное инкапсулирование информации (в отличие от 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):

Но более информативным является документация Popen:

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)

Выполните дочернюю программу в новом процессе. В POSIX класс использует os.execvp() - подобное поведение для выполнения дочерней программы. В Windows, класс использует функцию Windows CreateProcess(). Аргументы в Popen:

Понимание оставшейся документации на Popen будет оставлено как упражнение для читателя.

  • 0
    Простой пример двусторонней связи между основным процессом и подпроцессом можно найти здесь: stackoverflow.com/a/52841475/1349673
  • 0
    Первый пример, вероятно, должен иметь shell=True или (еще лучше) передать команду в виде списка.
22

Это может быть так просто:

import os
cmd = "your command"
os.system(cmd)
  • 0
    Это не указывает на недостатки, которые более подробно объясняются в PEP-324 . Документация для os.system явно рекомендует избегать этого в пользу subprocess .
22

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

import os

cmd = 'ls -al'

os.system(cmd)

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

Для более os функций здесь является документация.

  • 2
    это также устарело. использовать подпроцесс
19

subprocess.check_call удобно, если вы не хотите проверять возвращаемые значения. Он генерирует исключение при любой ошибке.

18

Я обычно использую subprocess вместе с 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)
17

os.system не позволяет сохранять результаты, поэтому, если вы хотите сохранить результаты в каком-то списке или что-то subprocess.call работает.

17

Здесь есть еще одна разница, которая не упоминается ранее.

subprocess.Popen выполняет <command> как подпроцесс. В моем случае мне нужно выполнить файл <a>, который должен связываться с другой программой, <b>.

Я попробовал подпроцесс, и выполнение было успешным. Однако <b> не удалось связаться с <a>. Все нормально, когда я запускаю оба терминала.

Еще одно: (ПРИМЕЧАНИЕ: kwrite ведет себя отличным от других приложений. Если вы попробуете приведенный ниже с Firefox, результаты будут не такими.)

Если вы попробуете os.system("kwrite"), программный поток зависает, пока пользователь не закроет kwrite. Чтобы преодолеть это, я попробовал вместо os.system(konsole -e kwrite). Эта программа продолжилась, но kwrite стал подпроцессом консоли.

Кто-нибудь запускает kwrite, не являющийся подпроцессом (т.е. в системном мониторе он должен появляться на крайнем левом краю дерева).

  • 1
    Что вы подразумеваете под «Кто-нибудь запускает kwrite, не будучи подпроцессом» ?
16

Мне очень нравится shell_command для его простоты. Он построен поверх модуля подпроцесса.

Вот пример из документов:

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

использовать модуль os

import os
os.system("your command")

например

import os
os.system("ifconfig")
  • 0
    Это дублирует (немного) более подробный ответ предыдущего апреля, который, однако, также не указывает на предостережения.
14

В Linux, если вы хотите вызвать внешнюю команду, которая будет выполняться независимо (будет работать после завершения python script), вы можете использовать простую очередь как диспетчер задач или at команда

Пример с диспетчером очереди задач:

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

Заметки о диспетчере очереди задач (ts):

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

    ts -S <number-of-slots>

  • Установка ts не требует прав администратора. Вы можете загрузить и скомпилировать его из источника с помощью простого make, добавить его в свой путь, и все готово.

  • 0
    ts не является стандартным для любого дистрибутива, о котором я знаю, хотя указатель на at немного полезен. Вы должны также упомянуть batch . Как и везде, в рекомендации os.system() следует, по крайней мере, упомянуть, что subprocess является его рекомендуемой заменой.
14

Бесстыдный плагин, я написал для этого библиотеку: P https://github.com/houqp/shell.py

В настоящее время это оболочка для popen и shlex. Он также поддерживает команды конвейеров, чтобы упростить цепочку команд в Python. Таким образом, вы можете делать такие вещи, как:

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

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

from subprocess import Popen

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

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

12

В 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
11

os.system был заменен модулем subprocess. Вместо этого используйте подпрограмму.

11

Чтобы получить идентификатор сети из нейтрона openstack:

#!/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
  • 0
    Вы не должны рекомендовать os.popen() в 2016 году. Сценарий Awk можно легко заменить на собственный код Python.
11

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

from commands import getstatusoutput

try:
    return getstatusoutput("ls -ltr")
except Exception, e:
    return None
  • 4
    Это будет устаревшим в Python 3.0?
  • 1
    Действительно, в документации по commands из Python 2.7 говорится, что она устарела в 2.6 и будет удалена в 3.0.
10

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

Это возвращаемые значения из метода 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]
  • 1
    Потенциал тупика: используйте метод .communicate
  • 0
    А еще лучше избегайте Popen() и используйте API более высокого уровня, который теперь собран в единственную функцию subprocess.run()
7

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
  • 0
    Это отличная библиотека. Я пытался объяснить это коллеге на днях, и adn описал это так: invoke - это subprocess а requests - urllib3 .
7

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

Python Subprocess check_output подходит для

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

import subprocess
proc = subprocess.check_output('ipconfig /all')
print proc
  • 0
    Аргумент должен быть правильно разбит на токены в список, или вы должны явно передать в shell=True . В Python 3.x (где, я думаю, x> 3) вы можете получить вывод в виде правильной строки с universal_newlines=True и вы, вероятно, захотите переключиться на subproces.run()
7

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

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',
 '']
7

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

Например:

In [9]: mylist = !ls

In [10]: mylist
Out[10]:
['file1',
 'file2',
 'file3',]
6

Вызов внешней команды в 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]
6

Существует множество различных способов запуска внешних команд в Python, и все они имеют свои собственные плюсы и недостатки.

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

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

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

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

5

Как пример (в 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.

  • 1
    Согласно docs.python.org/2/library/… , «shell = True» может вызвать проблемы безопасности.
  • 0
    @ Ник Предли: замечено, но «shell = False» не выполняет нужную функцию. Каковы конкретно проблемы безопасности и какова альтернатива? Пожалуйста, дайте мне знать как можно скорее: я не хочу публиковать что-либо, что может вызвать проблемы у любого, кто просматривает это.
Показать ещё 1 комментарий
5

Для 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)
  • 2
    Ответ с функцией запуска был добавлен в 2015 году. Вы повторили это. Я думаю, что это было причиной отрицательного голосования
4

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

Он получается, если процесс выполняется с использованием метода 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])
  • 1
    Вы получите неожиданные результаты, передав аргумент с пробелом. Использование repr(arg) вместо str(arg) может помочь простым совпадением того, что python и sh escape цитируют одинаково
  • 1
    @sbk repr(arg) не очень помогло, вышеприведенный код также обрабатывает пробелы. Теперь работает следующее exec_long_running_proc(command = "ls", args=["-l", "~/test file*"])
4

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

  • Например:

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

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

  • os.system(cmd,...)

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

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

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

import os
cmd = " ".join(exename,parameters)
os.popen(cmd)
  • 0
    os.popen не следует рекомендовать и, возможно, даже упоминать больше. subpocess должен передавать аргументы в виде списка, а не соединять их пробелами.
4

Использование функции 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
..
  • 0
    Это больше не правда, и, вероятно, не было, когда этот ответ был опубликован. Вы должны предпочесть subprocess.check_call() и друзей, если вам абсолютно не нужен элемент управления более низкого уровня более сложного Popen() . В последних версиях Python рабочая лошадка - subprocess.run()
4

Простым способом является использование модуля os:

import os
os.system('ls')

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

import subprocess
subprocess.check_call('ls')

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

import subprocess
r = subprocess.check_output('ls')
4

Используйте 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(" "))
3

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

Например,

!ls -ilF
2

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

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

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

pip install citizenshell

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

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

Вы можете отделить stdout от 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 + "!"

будет печатать строки, как они доступны, благодаря wait = 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.

2

Я бы порекомендовал следующий метод "запустить", и это поможет нам получить STDOUT, STDERR и статус выхода в качестве словаря; Вызывающий из этого может прочитать возврат словаря методом "запустить", чтобы узнать фактическое состояние процесса.

  def run (cmd):
       print "+ DEBUG exec({0})".format(cmd)
       p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True)
       (out, err) = p.communicate()
       ret        = p.wait()
       out        = filter(None, out.split('\n'))
       err        = filter(None, err.split('\n'))
       ret        = True if ret == 0 else False
       return dict({'output': out, 'error': err, 'status': ret})
  #end
  • 0
    Это не полностью переопределяет что-то вроде subprocess.run() . Особенно следует избегать shell=True когда это не является строго необходимым.
2

После некоторых исследований у меня есть следующий код, который очень хорошо работает для меня. Он в основном печатает как stdout, так и stderr в режиме реального времени. Надеюсь, это поможет кому-то, кому это нужно.

stdout_result = 1
stderr_result = 1


def stdout_thread(pipe):
    global stdout_result
    while True:
        out = pipe.stdout.read(1)
        stdout_result = pipe.poll()
        if out == '' and stdout_result is not None:
            break

        if out != '':
            sys.stdout.write(out)
            sys.stdout.flush()


def stderr_thread(pipe):
    global stderr_result
    while True:
        err = pipe.stderr.read(1)
        stderr_result = pipe.poll()
        if err == '' and stderr_result is not None:
            break

        if err != '':
            sys.stdout.write(err)
            sys.stdout.flush()


def exec_command(command, cwd=None):
    if cwd is not None:
        print '[' + ' '.join(command) + '] in ' + cwd
    else:
        print '[' + ' '.join(command) + ']'

    p = subprocess.Popen(
        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd
    )

    out_thread = threading.Thread(name='stdout_thread', target=stdout_thread, args=(p,))
    err_thread = threading.Thread(name='stderr_thread', target=stderr_thread, args=(p,))

    err_thread.start()
    out_thread.start()

    out_thread.join()
    err_thread.join()

    return stdout_result + stderr_result
  • 3
    Ваш код может потерять данные при выходе из подпроцесса, когда некоторые данные буферизируются. Читайте до EOF вместо этого, смотрите teed_call ()
1

Я написал обертку для обработки ошибок и перенаправления вывода и других вещей.

import shlex
import psutil
import subprocess

def call_cmd(cmd, stdout=sys.stdout, quiet=False, shell=False, raise_exceptions=True, use_shlex=True, timeout=None):
    """Exec command by command line like 'ln -ls "/var/log"'
    """
    if not quiet:
        print("Run %s", str(cmd))
    if use_shlex and isinstance(cmd, (str, unicode)):
        cmd = shlex.split(cmd)
    if timeout is None:
        process = subprocess.Popen(cmd, stdout=stdout, stderr=sys.stderr, shell=shell)
        retcode = process.wait()
    else:
        process = subprocess.Popen(cmd, stdout=stdout, stderr=sys.stderr, shell=shell)
        p = psutil.Process(process.pid)
        finish, alive = psutil.wait_procs([p], timeout)
        if len(alive) > 0:
            ps = p.children()
            ps.insert(0, p)
            print('waiting for timeout again due to child process check')
            finish, alive = psutil.wait_procs(ps, 0)
        if len(alive) > 0:
            print('process {} will be killed'.format([p.pid for p in alive]))
            for p in alive:
                p.kill()
            if raise_exceptions:
                print('External program timeout at {} {}'.format(timeout, cmd))
                raise CalledProcessTimeout(1, cmd)
        retcode = process.wait()
    if retcode and raise_exceptions:
        print("External program failed %s", str(cmd))
        raise subprocess.CalledProcessError(retcode, cmd)

Вы можете назвать это следующим образом:

cmd = 'ln -ls "/var/log"'
stdout = 'out.txt'
call_cmd(cmd, stdout)
1

Модуль подпроцесса описанный выше Eli, очень мощный, но синтаксис для создания системного вызова с болотным стандартом и проверки его вывода излишне проликс.

Самый простой способ сделать системный вызов - это модуль команд (только для Linux).

> import commands
> commands.getstatusoutput("grep matter alice-in-wonderland.txt")
(0, "'Then it doesn't matter which way you go,' said the Cat.")

Первым элементом кортежа является код возврата процесса. Второй элемент - его стандартный вывод (и стандартная ошибка, объединенная).


У разработчиков Python есть "устаревший" модуль команд, но это не значит, что вы не должны его использовать. Только то, что они не развивают его больше, что хорошо, потому что он уже совершенен (при его небольшой, но важной функции).

  • 8
    Устаревшее означает не только «больше не разрабатывается», но и «вам не рекомендуется использовать это». Устаревшие функции могут быть нарушены в любое время, могут быть удалены в любое время или могут быть опасными. Вы никогда не должны использовать это в важном коде. Устаревание - это просто лучший способ, чем немедленное удаление функции, поскольку она дает программистам время для адаптации и замены устаревших функций.
  • 3
    Просто чтобы доказать мою точку зрения: «Устаревшее с версии 2.6: модуль команд был удален в Python 3. Вместо этого используйте модуль подпроцесса».
Показать ещё 2 комментария
0

Существует два основных способа выполнения команд оболочки с использованием 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
0

Так как некоторые ответы были связаны с предыдущими версиями python или использовали модуль os.system я os.system этот ответ для людей, подобных мне, которые намереваются использовать subprocess в python 3.5+. Следующее помогло мне в Linux:

import subprocess

#subprocess.run() returns a completed process object that can be inspected
c = subprocess.run(["ls", "-ltrh"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(c.stdout.decode('utf-8'))

Как упомянуто в документации, значения PIPE являются байтовыми последовательностями, и для правильного их отображения необходимо учитывать декодирование. Для более поздних версий python text=True и encoding='utf-8' добавляются в kwargs subprocess.run().

Вывод вышеупомянутого кода:

total 113M
-rwxr-xr-x  1 farzad farzad  307 Jan 15  2018 vpnscript
-rwxrwxr-x  1 farzad farzad  204 Jan 15  2018 ex
drwxrwxr-x  4 farzad farzad 4.0K Jan 22  2018 scripts
.... # some other lines

Ещё вопросы

Сообщество Overcoder
Наверх
Меню