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

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

Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function
4461
задан Anonymous 14 September 2019 в 09:10
поделиться

15 ответов

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

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

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

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

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

Заменяющие Более старые Функции с разделом Module подпроцесса в subprocess документация может иметь некоторые полезные рецепты.

Для версий Python прежде 3.5, используйте call:

import subprocess
subprocess.call(["ls", "-l"])
4291
ответ дан Corey Goldberg 14 September 2019 в 09:10
поделиться
  • 1
    Спасибо за Ваш ответ, ссылка от Eric Lippert очень ценна, я все еще немного смущен, Ваше различие оператора применяется, когда CLR может гарантировать что это doesn' t должен внести какое-либо представительное изменение в значения ? это первые критерии должно применить различие? – cuongle 17 September 2012 в 08:16

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

subprocess.call(['ping', 'localhost'])
127
ответ дан cincodenada 14 September 2019 в 09:10
поделиться
import os
cmd = 'ls -al'
os.system(cmd)

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

126
ответ дан Patrick M 14 September 2019 в 09:10
поделиться
import os
os.system("your command")

Примечание, что это опасно, начиная с команды, не убрано. Я оставляю его до Вас к Google для соответствующей документации на 'OS' и 'sys' модулях. Существует набор функций (должностное лицо* и икра*), который сделает подобные вещи.

122
ответ дан Peter Mortensen 14 September 2019 в 09:10
поделиться

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

  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 что весь дескриптор i/o немного по-другому. Если Вы передаете все как строку, то Ваша команда передается оболочке; при передаче их как списка затем, Вы не должны волноваться о выходе ни из чего. См. документация .

  3. Popen класс subprocess модуль. Это предназначается как замена для [1 110], но имеет оборотную сторону того, чтобы быть немного более сложным на основании того, чтобы быть настолько всесторонним. Например, Вы сказали бы:

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

    вместо:

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

    , но хорошо иметь все опции там в одном объединенном классе вместо 4 различных функций popen. См. документация .

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

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

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

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

  6. модуль OS также имеет все функции ветвления/должностного лица/икры, которые Вы имели бы в программе C, но я не рекомендую использовать их непосредственно.

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

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

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

и предполагают, что пользователь входит, что-то "моя мама не любило меня & & комната-rf /" который мог стереть целую файловую систему.

2848
ответ дан mit 14 September 2019 в 09:10
поделиться

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

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

import os
os.system('cat testfile')
33
ответ дан Jonathan Callen 14 September 2019 в 09:10
поделиться

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

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

31
ответ дан Jim Fasarakis Hilliard 14 September 2019 в 09:10
поделиться

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

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

315
ответ дан Jim Fasarakis Hilliard 14 September 2019 в 09:10
поделиться

Python 3.5 +

import subprocess

p = subprocess.run(["ls", "-ltr"], capture_output=True)
print(p.stdout.decode(), p.stderr.decode())

Попытка онлайн

0
ответ дан Vishal 4 October 2019 в 06:59
поделиться
[

] Здесь есть еще одно отличие, которое ранее не упоминалось.[

] [

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

] [

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

] [

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

] [

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

] [

]Любой запустит kwrite не будучи подпроцессом (т.е. в системном мониторе он должен появиться на крайнем левом краю дерева)[

].
20
ответ дан 22 November 2019 в 19:37
поделиться

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

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

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

import subprocess
import sys

# some code here

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

# some more code here

Идея здесь в том, что вы не хотите ждать в строке «call subprocess», пока longtask.py не завершится. Но непонятно, что происходит после строки «еще немного кода» из примера.

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

В Windows (win xp) родительский процесс не завершится, пока longtask.py не завершит свою работу. Это не то, что вам нужно в CGI-скрипте. Проблема не является специфической для 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-скрипте это тоже не то. Некоторые эксперименты показали, что проблема заключалась в совместном использовании sys.stdout.И рабочее решение было следующее:

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

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

205
ответ дан 22 November 2019 в 19:37
поделиться

Если Вы пишете сценарий оболочки Python и имеете IPython, установленный в Вашей системе, можно использовать волшебство удара выполнить команду в IPython:

!ls
filelist = !ls
2
ответ дан 22 November 2019 в 19:37
поделиться
import subprocess

p = subprocess.run(["ls", "-ltr"], capture_output=True)
print(p.stdout.decode(), p.stderr.decode())

Попытка онлайн

1
ответ дан 22 November 2019 в 19:37
поделиться

Можно также использовать subprocess.getoutput() и subprocess.getstatusutput(), которые являются Наследие Функции Вызова Shell от устаревшего commands модуль, т.е.:

subprocess.getstatusoutput(cmd)

Возврат (exitcode, output) выполнения cmd в оболочке.

<час>

subprocess.getoutput(cmd)

вывод Возврата (stdout и stderr) выполнения cmd в оболочке.

0
ответ дан 22 November 2019 в 19:37
поделиться

Можно использовать import и затем имя файла. Например, с помощью встроенного 'случайного' модуля: import random

-1
ответ дан 22 November 2019 в 19:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: