527 Stimmen

Bash-Befehle in Python ausführen

Auf meinem lokalen Rechner führe ich ein Python-Skript aus, das diese Zeile enthält

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
os.system(bashCommand)

Das funktioniert gut.

Wenn ich dann denselben Code auf einem Server ausführe, erhalte ich folgende Fehlermeldung

'import site' failed; use -v for traceback
Traceback (most recent call last):
File "/usr/bin/cwm", line 48, in <module>
from swap import  diag
ImportError: No module named swap

Ich habe also eine print bashCommand das mir dann den Befehl im Terminal ausgibt, bevor es ihn mit os.system() .

Natürlich erhalte ich wieder den Fehler (verursacht durch os.system(bashCommand) ), aber vor diesem Fehler gibt es den Befehl im Terminal aus. Dann habe ich diese Ausgabe einfach kopiert und in das Terminal eingefügt und die Eingabetaste gedrückt und es funktioniert...

Hat jemand eine Ahnung, was hier los ist?

9voto

ricardo130 Punkte 146

Sie können auch 'os.popen' verwenden. Beispiel:

import os

command = os.popen('ls -al')
print(command.read())
print(command.close())

Ausgabe:

total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root   77 ago 13 21:53 test.py

None

8voto

kichik Punkte 30440

Laut der Fehlermeldung fehlt Ihnen ein Paket namens tauschen. auf dem Server. Diese /usr/bin/cwm erfordert es. Wenn Sie mit Ubuntu/Debian arbeiten, installieren Sie python-swap mit Aptitude.

7voto

jfs Punkte 370717

Um den Befehl ohne eine Shell auszuführen, übergeben Sie den Befehl als Liste und implementieren die Umleitung in Python mit [subprocess] :

#!/usr/bin/env python
import subprocess

with open('test.nt', 'wb', 0) as file:
    subprocess.check_call("cwm --rdf test.rdf --ntriples".split(),
                          stdout=file)

Anmerkung: keine > test.nt am Ende. stdout=file setzt die Umleitung um.


Um den Befehl über die Shell in Python auszuführen, übergeben Sie den Befehl als String und ermöglichen shell=True :

#!/usr/bin/env python
import subprocess

subprocess.check_call("cwm --rdf test.rdf --ntriples > test.nt",
                      shell=True)

Hier ist die Shell für die Umleitung der Ausgabe zuständig ( > test.nt in dem Befehl steht).


Um einen Bash-Befehl auszuführen, der Bashismen verwendet, geben Sie die ausführbare Bash-Datei explizit an, z. B. an Bash-Prozess-Ersatz emulieren :

#!/usr/bin/env python
import subprocess

subprocess.check_call('program <(command) <(another-command)',
                      shell=True, executable='/bin/bash')

1voto

RewordedAnswers Punkte 19

Der pythonische Weg, dies zu tun, ist die Verwendung von subprocess.Popen

subprocess.Popen nimmt eine Liste, in der das erste Element der auszuführende Befehl ist, gefolgt von eventuellen Befehlszeilenargumenten.

Ein Beispiel:

import subprocess

args = ['echo', 'Hello!']
subprocess.Popen(args) // same as running `echo Hello!` on cmd line

args2 = ['echo', '-v', '"Hello Again"']
subprocess.Popen(args2) // same as running 'echo -v "Hello Again!"` on cmd line

1voto

dux2 Punkte 1600

subprocess.Popen() ist vorzuziehen gegenüber os.system() da es mehr Kontrolle und Sichtbarkeit bietet. Wenn Sie jedoch finden subprocess.Popen() zu langatmig oder zu komplex, peasyshell ist ein kleiner Wrapper, den ich darüber geschrieben habe und der es einfach macht, von Python aus mit Bash zu interagieren.

https://github.com/davidohana/peasyshell

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X