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


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.


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.


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

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")

15

Verwenden Sie das Unterprozessmodul wie oben erwähnt.

Ich benutze es so:

subprocess.call(["notepad"])

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


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.


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"


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'])

1

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

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

-9

Bitte versuchen Sie die folgenden Codes:

Import Execute 

Execute("zbx_control.sh")
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.