Як викликати скрипт оболонки з коду python?


Відповіді:


252

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

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

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

Де test.shпростий скрипт оболонки і 0його повернене значення для цього запуску.


11
Примітка: бажано передавати subprocess.call () список, а не рядок (див. Команду Hugo24 нижче для прикладу та причин).
Джим Денніс

1
Посилання на підручник розірвано.
Kshitij Saraogi

6
Це дає: OSError: [Errno 13] Дозвіл відхилено. мій сценарій не потрібно запускати з sudo. @Manoj Govindan
alper

6
З аргументами: subprocess.call (['./ test.sh', 'param1', 'param2'])
Генрі

2
@alper перейти в папку , де ви розмістили скрипт і запустити команду chmod +x script.sh. Примітка: script.sh є заповнювачем вашого сценарію, замініть його відповідно.
Tom J Muthirenthi

105

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

import os
os.system(command)

є одним із найпростіших.


1
чому це не найбільш відповідна відповідь? Чи не потрібно імпортувати модуль кращого рішення? Тут повинен бути якийсь недолік?
boulder_ruby

6
За допомогою subprocessвас можна керувати вхідними / вихідними / помилковими трубами. Так само краще, коли у вас буде багато аргументів - з os.command()вами доведеться створити цілий командний рядок з утеченими спеціальними символами, при subprocessцьому є простий список аргументів. Але для простих завдань os.command() може бути просто достатньо.
Michał Niklas

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

Це елегантно.
Калеб


15

Використовуйте модуль підпроцесу, як згадувалося вище.

Я використовую це так:

subprocess.call(["notepad"])

13
Примітка: виклик підпроцесу зі списком є ​​більш безпечним, оскільки він не потребує передачі (потенційно несанітованої) рядку через оболонку для розбору / інтерпретації. Першим пунктом у списку буде виконуваний файл, а всі інші елементи передаватимуться як аргументи.
Джим Денніс

13

Я запускаю python 3.5 і subprocess.call (['./ test.sh']) для мене не працює.

Я даю вам три рішення залежить від того, що ви хочете зробити з результатом.

1 - сценарій виклику. Ви побачите вихід у своєму терміналі. вихід - число.

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

2 - виконання і помилка виклику та помилка в рядку. Ви не бачите виконання у своєму терміналі, якщо ви не надрукуєте (stdout). Shell = Вірно, оскільки аргумент у Попена не працює для мене.

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 - скрипт виклику та скидання команд ехо команд 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


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 Subprocess як змінено з python 3.5.

Новий спосіб виконання зовнішніх скриптів - це runфункція, яка виконує команду, описану args. Чекає завершення команди, а потім повертає екземпляр CompletedProcess.

import subprocess

subprocess.run(['./test.sh'])

1

Якщо ваш файл сценарію оболонки не має дозволів на виконання, зробіть це наступним чином.

import subprocess
subprocess.run(['/bin/bash', './test.sh'])

-9

Будь ласка, спробуйте наступні коди:

Import Execute 

Execute("zbx_control.sh")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.