Как вызвать скрипт из кода Python?

Ответы:

252

Модуль подпроцесса поможет вам.

Очевидно тривиальный пример:

>>> import subprocess
>>> subprocess.call(['./test.sh']) # Thanks @Jim Dennis for suggesting the []
0 
>>> 

Где test.shпростой сценарий оболочки и 0его возвращаемое значение для этого прогона.

Маной Говиндан
источник
11
Примечание: предпочтительно передавать subprocess.call () список, а не строку (см. Команду Hugo24 ниже для примера и причин).
Джим Деннис
1
Ссылка на учебник не работает.
Кшитий Сараоги
6
Это дает: OSError: [Errno 13] В доступе отказано. Мой сценарий не требуется для запуска с sudo. @Manoj Говиндан
Alper
6
С аргументами: subprocess.call (['./ test.sh', 'param1', 'param2'])
Генри
2
@alper перейти в папку , где вы разместили скрипт и запустить команду chmod +x script.sh. Примечание: script.sh является заполнителем для вашего скрипта, замените его соответствующим образом.
Том Дж Мутиренти
106

Есть несколько способов использования os.popen()(не рекомендуется) или всего subprocessмодуля, но этот подход

import os
os.system(command)

является одним из самых простых.

Михал Никлас
источник
1
почему это не самый одобренный ответ? Разве не нужно импортировать модуль лучше? Должен ли быть какой-то недостаток здесь?
boulder_ruby
6
С помощью subprocessвы можете управлять вводом / выводом / ошибкой каналов. Также лучше, когда у вас много аргументов - os.command()вам придется создавать целую командную строку с экранированием специальных символов, с subprocessпростым списком аргументов. Но для простых задач os.command() может быть просто достаточно.
Михал Никлас
1
Цитировать по этой ссылке:The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; *using that module is preferable to using this function.*
Максимилиан
42

Если вы хотите передать некоторые параметры в ваш скрипт оболочки, вы можете использовать метод shlex.split () :

import subprocess
import shlex
subprocess.call(shlex.split('./test.sh param1 param2'))

с test.shв той же папке:

#!/bin/sh
echo $1
echo $2
exit 0

Выходы:

$ python test.py 
param1
param2
Франк Дернонкур
источник
Это элегантно.
Калеб
20
import os
import sys

Предполагая, что test.sh является сценарием оболочки, который вы хотите выполнить

os.system("sh test.sh")
Срайан Гухатхакурта
источник
15

Используйте модуль подпроцесса, как указано выше.

Я использую это так:

subprocess.call(["notepad"])
hugo24
источник
13
Примечание: вызов подпроцесса со списком более безопасен, так как не требует пропуска (потенциально неанизированной) строки через оболочку для анализа / интерпретации. Первым элементом в списке будет исполняемый файл, а все остальные элементы будут переданы в качестве аргументов.
Джим Деннис
13

Я использую Python 3.5 и subprocess.call (['./ test.sh']) не работает для меня.

Я даю вам три решения, зависит от того, что вы хотите сделать с выходом.

1 - скрипт вызова. Вы увидите вывод в вашем терминале. выходной это число.

import subprocess 
output = subprocess.call(['test.sh'])

2 - вызов и сброс дампа и ошибка в строку. Вы не увидите выполнение в своем терминале, если не печатаете (stdout). Shell = True, поскольку аргумент в Popen не работает для меня.

import subprocess
from subprocess import Popen, PIPE

session = subprocess.Popen(['test.sh'], stdout=PIPE, stderr=PIPE)
stdout, stderr = session.communicate()

if stderr:
    raise Exception("Error "+str(stderr))

3 - вызвать скрипт и вывести команды echo файла temp.txt в файл temp_file

import subprocess
temp_file = open("temp.txt",'w')
subprocess.call([executable], stdout=temp_file)
with open("temp.txt",'r') as file:
    output = file.read()
print(output)

Не забудьте взглянуть на подпроцесс doc

lauralacarra
источник
1
Примечание. Не используйте stdout = PIPE или stderr = PIPE с subprocess.call. Дочерний процесс блокируется, если он генерирует достаточно данных для канала, чтобы заполнить буфер канала ОС, поскольку каналы не читаются из.
4

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

subprocess.call(["ls","-l"]);
#basic syntax
#subprocess.call(args, *)

Вы можете увидеть его документацию здесь.

Если ваш скрипт написан в каком-то файле .sh или длинной строке, то вы можете использовать модуль os.system. Это довольно просто и легко позвонить:

import os
os.system("your command here")
# or
os.system('sh file.sh')

Эта команда запустит скрипт один раз, до его завершения и заблокирует, пока он не выйдет.

Анкит Сингх
источник
Вам не нужно импортировать sys тоже?
ScottyBlades
Нет, ты не; попробуйте открыть оболочку Python и запустить этот фрагмент
Декарт
4

В случае, если скрипт имеет несколько аргументов

#!/usr/bin/python

import subprocess
output = subprocess.call(["./test.sh","xyz","1234"])
print output

Выход выдаст код состояния. Если скрипт выполняется успешно, он даст 0, иначе ненулевое целое число.

podname=xyz  serial=1234
0

Ниже приведен скрипт оболочки test.sh.

#!/bin/bash

podname=$1
serial=$2
echo "podname=$podname  serial=$serial"
Риши Бансал
источник
2

Подпроцесс хорош, но некоторым людям может понравиться сценарий лучше. Scriptine имеет более высокоуровневый набор методов, таких как shell.call (args) , path.rename (new_name) и path.move (src, dst) . Скриптин основан на подпроцессе и других.

Два недостатка скриптинга:

  • Текущий уровень документации будет более полным, даже если этого достаточно.
  • В отличие от подпроцесса, скрипт-пакет в настоящее время не установлен по умолчанию.
Аксели Пален
источник
2

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

Новый способ выполнения внешних скриптов - с помощью runфункции, которая запускает команду, описанную args. Ожидает завершения команды, затем возвращает экземпляр CompletedProcess.

import subprocess

subprocess.run(['./test.sh'])
Кевин Санчес Лакруа
источник
1

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

import subprocess
subprocess.run(['/bin/bash', './test.sh'])
thomasXu
источник
-9

Пожалуйста, попробуйте следующие коды:

Import Execute 

Execute("zbx_control.sh")
Manas
источник