Wie rufe ich ein Shell-Skript aus Python-Code auf?

210

Wie rufe ich ein Shell-Skript aus Python-Code auf?

Umesh K.
quelle

Antworten:

252

Das Unterprozessmodul hilft Ihnen dabei.

Offensichtlich triviales Beispiel:

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

Wo test.shist ein einfaches Shell-Skript und 0ist sein Rückgabewert für diesen Lauf.

Manoj Govindan
quelle
11
Hinweis: Es ist vorzuziehen, subprocess.call () eine Liste anstelle einer Zeichenfolge zu übergeben (Beispiel und Gründe siehe Befehl an Hugo24 unten).
Jim Dennis
1
Der Link zum Tutorial ist unterbrochen.
Kshitij Saraogi
6
Dies ergibt: OSError: [Errno 13] Berechtigung verweigert. Mein Skript muss nicht mit sudo ausgeführt werden. @ Manoj Govindan
Alper
6
Mit Argumenten: subprocess.call (['./ test.sh', 'param1', 'param2'])
Henry
2
@alper Gehen Sie in den Ordner, in dem Sie das Skript abgelegt haben, und führen Sie den Befehl aus chmod +x script.sh. Hinweis: script.sh ist ein Platzhalter für Ihr Skript. Ersetzen Sie ihn entsprechend.
Tom J Muthirenthi
105

Es gibt einige Möglichkeiten, os.popen()(veraltet) oder das gesamte subprocessModul zu verwenden, aber diesen Ansatz

import os
os.system(command)

ist einer der einfachsten.

Michał Niklas
quelle
1
Warum ist dies nicht die am besten bewertete Antwort? Ist es nicht die bessere Lösung, kein Modul importieren zu müssen? Muss hier ein Nachteil sein?
boulder_ruby
6
Mit können subprocessSie Eingabe- / Ausgabe- / Fehlerleitungen verwalten. Es ist auch besser, wenn Sie viele Argumente haben - mit müssen os.command()Sie eine ganze Befehlszeile mit Escapezeichen für Sonderzeichen erstellen, mit einer subprocesseinfachen Liste von Argumenten. Aber für einfache Aufgaben os.command() kann gerade noch ausreichen.
Michał Niklas
1
Um aus diesem Link zu zitieren:The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; *using that module is preferable to using this function.*
Maximilian
42

Wenn Sie einige Parameter an Ihr Shell-Skript übergeben möchten, können Sie die Methode shlex.split () verwenden :

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

mit test.shim selben Ordner:

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

Ausgänge:

$ python test.py 
param1
param2
Franck Dernoncourt
quelle
Das ist elegant.
Caleb
20
import os
import sys

Angenommen, test.sh ist das Shell-Skript, das Sie ausführen möchten

os.system("sh test.sh")
Srayan Guhathakurta
quelle
15

Verwenden Sie das Unterprozessmodul wie oben erwähnt.

Ich benutze es so:

subprocess.call(["notepad"])
hugo24
quelle
13
Hinweis: Das Aufrufen eines Unterprozesses mit einer Liste ist sicherer, da die (möglicherweise nicht bereinigte) Zeichenfolge nicht zum Parsen / Interpretieren durch eine Shell geleitet werden muss. Das erste Element in der Liste ist die ausführbare Datei, und alle anderen Elemente werden als Argumente übergeben.
Jim Dennis
13

Ich verwende Python 3.5 und subprocess.call (['./ test.sh']) funktioniert bei mir nicht.

Ich gebe Ihnen drei Lösungen, die davon abhängen, was Sie mit der Ausgabe machen möchten.

1 - Skript aufrufen. Sie sehen die Ausgabe in Ihrem Terminal. Ausgabe ist eine Zahl.

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

2 - Aufruf und Dump-Ausführung und Fehler in Zeichenfolge. Sie sehen die Ausführung in Ihrem Terminal nur, wenn Sie drucken (stdout). Shell = True, da das Argument in Popen bei mir nicht funktioniert.

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 - Rufen Sie das Skript auf und sichern Sie die Echo-Befehle von temp.txt in 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)

Vergessen Sie nicht, sich den doc-Unterprozess anzusehen

lauralacarra
quelle
1
Hinweis Verwenden Sie nicht stdout = PIPE oder stderr = PIPE mit subprocess.call. Der untergeordnete Prozess wird blockiert, wenn er genügend Ausgabe für eine Pipe generiert, um den OS-Pipe-Puffer zu füllen, da die Pipes nicht gelesen werden.
4

Das Unterprozessmodul ist ein gutes Modul zum Starten von Unterprozessen. Sie können es verwenden, um Shell-Befehle wie folgt aufzurufen:

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

Die Dokumentation finden Sie hier.

Wenn Sie Ihr Skript in eine .sh-Datei oder eine lange Zeichenfolge geschrieben haben, können Sie das Modul os.system verwenden. Es ist ziemlich einfach und leicht anzurufen:

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

Dieser Befehl führt das Skript einmal vollständig aus und blockiert es, bis es beendet wird.

Ankit Singh
quelle
Müssen Sie nicht auch sys importieren?
ScottyBlades
Nein, tust du nicht; Versuchen Sie, eine Python-Shell zu öffnen und dieses Snippet
Descartes
4

Falls das Skript mehrere Argumente hat

#!/usr/bin/python

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

Die Ausgabe gibt den Statuscode aus. Wenn das Skript erfolgreich ausgeführt wird, gibt es 0, andernfalls eine Ganzzahl ungleich Null.

podname=xyz  serial=1234
0

Unten finden Sie das Shell-Skript test.sh.

#!/bin/bash

podname=$1
serial=$2
echo "podname=$podname  serial=$serial"
Rishi Bansal
quelle
2

Der Unterprozess ist gut, aber einige Leute mögen Scriptine vielleicht besser. Scriptine verfügt über mehr Methoden auf hoher Ebene wie shell.call (args) , path.rename (neuer_name) und path.move (src, dst) . Scriptine basiert auf Unterprozessen und anderen.

Zwei Nachteile von Scriptine:

  • Der aktuelle Dokumentationsstand wäre umfassender, obwohl er ausreicht.
  • Im Gegensatz zum Unterprozess ist das Scriptine-Paket derzeit nicht standardmäßig installiert.
Akseli Palén
quelle
2

Ich weiß, dass dies eine alte Frage ist, aber ich bin kürzlich darauf gestoßen, und sie hat mich seit der Subprozess- API, die seit Python 3.5 geändert wurde , irregeführt .

Die neue Methode zum Ausführen externer Skripte ist die runFunktion, mit der der von args beschriebene Befehl ausgeführt wird. Wartet auf den Abschluss des Befehls und gibt dann eine CompletedProcess-Instanz zurück.

import subprocess

subprocess.run(['./test.sh'])
Kévin Sanchez Lacroix
quelle
1

Wenn Ihre Shell-Skriptdatei keine Ausführungsberechtigungen hat, gehen Sie folgendermaßen vor.

import subprocess
subprocess.run(['/bin/bash', './test.sh'])
thomasXu
quelle
-9

Bitte versuchen Sie die folgenden Codes:

Import Execute 

Execute("zbx_control.sh")
Manas
quelle