Запуск сценарію bash з python


105

У мене проблема із наступним кодом:

callBash.py:

import subprocess
print "start"
subprocess.call("sleep.sh")
print "end"

сон.ш:

sleep 10

Я хочу, щоб "кінець" був надрукований через 10 с. (Я знаю, що це тупий приклад, я міг просто спати всередині python, але цей простий файл sleep.sh був просто тестом)


Я також спробував це з "$! Bin / bash; sleep 10;"
user1638145

Незрозуміло, яку проблему намагається задати цей запитуваний, але це питання, мабуть, має залишитися, оскільки він накопичив історичну сумку більш-менш хороших здогадок як відповідей. Можливо також пошук конкретної помилки, і / або прочитати схожі питання , як stackoverflow.com/questions/4256107 / ...
tripleee

Відповіді:


91

Зробити файл dream.sh виконуваним та додавання shell=Trueдо списку параметрів (як це пропонується у попередніх відповідях) працює нормально. Залежно від шляху пошуку, вам може знадобитися додати ./або якийсь інший відповідний шлях. (Тобто, змінити "sleep.sh"на "./sleep.sh".)

shell=TrueПараметр не потрібен ( в рамках системи Posix , як Linux) , якщо перший рядок сценарію Баш є шлях до оболонки; наприклад, #!/bin/bash.


48

Якщо sleep.shу shebang #!/bin/shє відповідні права доступу chmod u+rx sleep.shдо файлів - запустіть, щоб переконатися, що він знаходиться, $PATHтоді ваш код повинен працювати так:

import subprocess

rc = subprocess.call("sleep.sh")

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

from subprocess import call

rc = call("./sleep.sh")

Якщо в сценарії немає шебанга, вам потрібно вказати shell=True:

rc = call("./sleep.sh", shell=True)

Якщо сценарій не має дозволу на виконання, і ви не можете його змінити, наприклад, запустивши os.chmod('sleep.sh', 0o755)його, ви можете прочитати сценарій як текстовий файл і передати рядок на subprocessмодуль:

with open('sleep.sh', 'rb') as file:
    script = file.read()
rc = call(script, shell=True)

34

Насправді вам просто потрібно додати shell=Trueаргумент:

subprocess.call("sleep.sh", shell=True)

Але будьте обережні -

Попередження Виклик системної оболонки з оболонкою = True може становити загрозу безпеці, якщо поєднувати з ненадійним входом Докладніше див. Попередження у розділі "Часто використовувані аргументи".

джерело


1
Він не працюватиме, якщо sleep.shйого немає PATH. І якщо він знаходиться в дорозі , і він має правильну хатину , то вам не потрібно shell=True. Дивіться мою відповідь
jfs

16

Якщо хтось шукає викликати сценарій з аргументами

import subprocess

val = subprocess.check_call("./script.sh '%s'" % arg, shell=True)

Не забудьте перетворити аргументи в рядок перед передачею, використовуючи str (arg).

Це можна використати для передачі бажаної кількості аргументів:

subprocess.check_call("./script.ksh %s %s %s" % (arg1, str(arg2), arg3), shell=True)

10

Переконайтеся, що sleep.shмає дозволи на виконання, і запустіть його shell=True:

#!/usr/bin/python

import subprocess
print "start"
subprocess.call("./sleep.sh", shell=True)
print "end"

так це була оболонка = Правда я пропустив. Чи можете ви пояснити, чому недостатньо встановити #! Bin / bash у першому рядку sc scrpt?
користувач1638145

3
Помилка в програмі #!bin/bashвідсутня /. #!/bin/bashпрацює, як я зазначаю у відповіді.
Джеймс Уолдбі - jwpat7

9

Якщо chmod не працює, ви також спробуйте

import os
os.system('sh script.sh')
#you can also use bash instead of sh

тест мені спасибі


os.systemДокументація спеціально рекомендує уникати його на користь subprocess( в ці дні, subprocess.run()). Якщо ви не можете взяти subprocessна роботу, швидше за все, у вас виникнуть проблеми os.system().
трійка

3

Додавання відповіді, тому що мене тут направили після запитання, як запустити bash-скрипт із python. Ви отримуєте помилку, OSError: [Errno 2] file not foundякщо ваш сценарій приймає параметри. Скажімо, наприклад, що ваш сценарій взяв параметр часу сну: subprocess.call("sleep.sh 10")не буде працювати, ви повинні передавати його як масив:subprocess.call(["sleep.sh", 10])


Ви повинні зрозуміти власне значення,shell=True але так, зазвичай, уникаючи цього, це ваша найкраща гра.
трійка
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.