Ausführen des Bash-Skripts in Python

104

Ich habe ein Problem mit dem folgenden Code:

callBash.py:

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

sleep.sh:

sleep 10

Ich möchte, dass das "Ende" nach 10 Sekunden gedruckt wird. (Ich weiß, dass dies ein dummes Beispiel ist, ich könnte einfach in Python schlafen, aber diese einfache Datei sleep.sh war nur ein Test)

user1638145
quelle
Ich habe es auch mit "$! Bin / bash; sleep 10;"
versucht
Es ist unklar, um welches Problem es sich bei diesem Questien handelt, aber die Frage sollte wahrscheinlich bleiben, da sich eine historische Sammlung von mehr oder weniger guten Vermutungen als Antworten angesammelt hat. Suchen Sie wahrscheinlich auch nach Ihrem spezifischen Fehler und / oder lesen Sie verwandte Fragen wie stackoverflow.com/questions/4256107/…
Tripleee

Antworten:

90

Die Ausführung von sleep.sh und das Hinzufügen shell=Truezur Parameterliste (wie in den vorherigen Antworten vorgeschlagen) funktioniert einwandfrei. Abhängig vom Suchpfad müssen Sie möglicherweise auch ./einen anderen geeigneten Pfad hinzufügen . (Dh, wechseln Sie "sleep.sh"zu "./sleep.sh".)

Der shell=TrueParameter wird nicht benötigt (unter einem Posix-System wie Linux), wenn die erste Zeile des Bash-Skripts ein Pfad zu einer Shell ist. zum Beispiel #!/bin/bash.

James Waldby - jwpat7
quelle
47

Wenn sleep.shder Shebang #!/bin/shund die entsprechenden Dateiberechtigungen vorhanden sind, führen Sie ihn aus chmod u+rx sleep.sh, um sicherzustellen, dass er vorhanden ist. $PATHDann sollte Ihr Code wie folgt funktionieren:

import subprocess

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

Wenn sich das Skript nicht im PATH befindet, geben Sie den vollständigen Pfad dazu an, z. B. wenn es sich im aktuellen Arbeitsverzeichnis befindet:

from subprocess import call

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

Wenn das Skript keinen Shebang hat, müssen Sie Folgendes angeben shell=True:

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

Wenn das Skript keine ausführbaren Berechtigungen hat und Sie es nicht ändern können, z. B. durch Ausführen, können os.chmod('sleep.sh', 0o755)Sie das Skript als Textdatei lesen und subprocessstattdessen die Zeichenfolge an das Modul übergeben:

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

Eigentlich muss man nur das shell=TrueArgument hinzufügen :

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

Aber Vorsicht -

Warnung Das Aufrufen der System-Shell mit shell = True kann ein Sicherheitsrisiko darstellen, wenn es mit nicht vertrauenswürdigen Eingaben kombiniert wird. Weitere Informationen finden Sie in der Warnung unter Häufig verwendete Argumente.

Quelle

Zenpoy
quelle
1
Es wird nicht funktionieren, wenn sleep.shnicht in der PATH. Und wenn es ist auf dem Weg , und es hat den richtigen shebang dann brauchen Sie nicht shell=True. Siehe meine Antwort
jfs
16

Wenn jemand ein Skript mit Argumenten aufrufen möchte

import subprocess

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

Denken Sie daran, die Argumente vor dem Übergeben mit str (arg) in einen String umzuwandeln.

Dies kann verwendet werden, um so viele Argumente wie gewünscht zu übergeben:

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

Stellen Sie sicher, dass das sleep.shüber Ausführungsberechtigungen verfügt, und führen Sie es aus mit shell=True:

#!/usr/bin/python

import subprocess
print "start"
subprocess.call("./sleep.sh", shell=True)
print "end"
Adam Matan
quelle
also war es die Shell = True, die ich verpasst habe. Können Sie erklären, warum es nicht ausreicht, #! Bin / bash in die erste Zeile des sh scricpt zu setzen?
user1638145
3
Der Fehler in #!bin/bashist ein fehlender /. #!/bin/bashfunktioniert wie ich in einer Antwort notiere.
James Waldby - jwpat7
9

Wenn chmod nicht funktioniert, versuchen Sie es auch

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

Test von mir danke

Harry1992
quelle
In der os.systemDokumentation wird ausdrücklich empfohlen, dies zu vermeiden subprocess(heutzutage subprocess.run()). Wenn Sie nicht subprocesszur Arbeit kommen können, haben Sie wahrscheinlich auch Probleme damit os.system().
Tripleee
3

Hinzufügen einer Antwort, da ich hierher geleitet wurde, nachdem ich gefragt hatte, wie ein Bash-Skript von Python ausgeführt werden soll. Sie erhalten eine Fehlermeldung, OSError: [Errno 2] file not foundwenn Ihr Skript Parameter übernimmt. Nehmen wir zum Beispiel an, Ihr Skript hat einen Ruhezeitparameter aufgenommen: Funktioniert subprocess.call("sleep.sh 10")nicht, Sie müssen ihn als Array übergeben:subprocess.call(["sleep.sh", 10])

Matthew Lang
quelle
Sie müssen die tatsächliche Bedeutung vonshell=True verstehen, aber ja, normalerweise ist es Ihr bestes Spiel, dies zu vermeiden.
Tripleee