wake-up-neo.com

Terminalbefehl von Python aus in neuem Terminalfenster ausführen?

Das Ziel hier ist, eine neue Python-Datei in einer neuen Shell und eine vorhandene Python-Datei in einer vorhandenen Shell auszuführen. Angenommen, ich habe zwei Dateien, aaa.py und bbb.py. Sagen wir der Einfachheit halber, dass alles, was aaa.py tut, ist ...

subprocess.call('python bbb.py', Shell=True)

... und sagen wir, dass bbb.py das tut ...

print 'It worked'

Jetzt ist es das Ziel, aaa.py in Terminal 1 auszuführen und es zu veranlassen, bbb.py in Terminal 2 zu starten. 

subprocess.call_in_new_window('python bb.py', Shell=True)
15
Evan Cathcart

Es gibt keine Möglichkeit, dies im Allgemeinen von einer Shell aus zu tun. Sie müssen das Terminal-Programm selbst oder ein Launcher-Programm ausführen, das dies für Sie tut. Und die Vorgehensweise ist für jedes Terminalprogramm unterschiedlich.

In einigen Fällen wird os.startfile das tun, was Sie möchten, aber dies wird nicht universell sein.

Beachten Sie im Allgemeinen auch, dass Sie tatsächlich einen absoluten Pfad zu Ihrem Skript benötigen, da im neuen Terminalfenster eine neue Shell ausgeführt wird und daher nicht unbedingt dasselbe Arbeitsverzeichnis vorhanden ist. Aber ich werde das für die Beispiele ignorieren.


Bei Windows cmd ist dies am einfachsten mit dem Befehl start Shell möglich. Wenn start ein beliebiges Befehlszeilenprogramm ist, einschließlich python, wird ein neues Cmd-Fenster angezeigt. So etwas wie:

subprocess.call('start /wait python bb.py', Shell=True)

OS X hat einen ähnlichen Befehl: open . Und es ist eher ein echtes Programm als ein Shell-Befehl, so dass Sie Shell=True nicht benötigen. Beim Ausführen eines Befehlszeilenprogramms oder -skripts mit open wird im Allgemeinen kein neues Terminalfenster geöffnet. In der Tat ist es der springende Punkt, dass Sie Programme so ausführen können, als würden sie im Finder doppelt angeklickt. Dabei wird nie etwas im Terminal ausgeführt, es sei denn, es handelt sich um eine .command-Datei.

Sie können also eine temporäre .command-Wrapper-Datei und open das erstellen. so etwas (ungetestet):

with tempfile.NamedTemporaryFile(suffix='.command') as f:
    f.write('#!/bin/sh\npython bb.py\n')
    subprocess.call(['open', '-W', f.name])

Alternativ können Sie open explizit die Verwendung von Terminal.app anweisen, etwa wie folgt:

subprocess.call(['open', '-W', '-a', 'Terminal.app', 'python', '--args', 'bb.py'])

Oder Sie können Terminal.app über AppleEvents ein Skript erstellen. Zum Beispiel:

appscript.app('Terminal').do_script('python bb.py')

Das Ereignis "do script" öffnet ein neues Fenster und führt sein Argument als Befehl aus. Wenn Sie eine detailliertere Steuerung wünschen, öffnen Sie das Skriptwörterbuch im AppleScript Editor und sehen Sie alle nützlichen Dinge, die Sie tun können.


Unter Linux oder anderen * nix-Systemen gibt es 65.102 verschiedene Desktop-Umgebungen, Launchers und Terminal-Programme. Müssen Sie an allen arbeiten?

Wenn Sie mit gnome-terminal das Terminal erneut ausführen, erhalten Sie ein neues Fenster. Mit dem Argument -x können Sie einen ersten Befehl angeben.

subprocess.call(['gnome-terminal', '-x', 'python bb.py'])

Viele ältere Terminals versuchen, mit xterm kompatibel zu sein, was dasselbe mit -e tut, also:

subprocess.call(['xterm', '-e', 'python bb.py'])
subprocess.call(['rxvt', '-e', 'python bb.py'])

… usw.

Woher wissen Sie, welches Terminal der Benutzer verwendet? Gute Frage. Sie können wie Elternprozesse von sich aus gehen, bis Sie etwas finden, das wie ein Terminal aussieht. Oder Sie könnten einfach davon ausgehen, dass jeder xterm hat. Oder Sie schauen sich an, wie verschiedene Distributionen ein Standardterminal konfigurieren und danach suchen. Oder…

25
abarnert

Sie werden das nicht schaffen können, zumindest nicht so einfach, wie Sie darüber nachdenken. Ich vermute, dass Sie wegen "Terminalfenster" von einem Mac sprechen.

Möglicherweise können Sie dies mithilfe des X Window-Systems verwirklichen. Sie benötigen jedoch eine Reihe von Einstellungen, X-Server, Berechtigungen usw., um dies zu ermöglichen.

Heutzutage verletzen solche Dinge normalerweise die normalen Sicherheitsgrenzen. Angenommen, Sie laden ein Programm herunter, das sich so verhält, wie Sie es vorschlagen. Es öffnet sich ein Fenster (Terminal) (für Sie unsichtbar), das die gleichen Berechtigungen hat wie Sie. Anschließend werden alle Verzeichnisse und Dateien gelesen und an den Ersteller des Programms gesendet. Sie könnten damit nicht zufrieden sein. Die ganze Zeit glaubst du, du spielst ein Spiel, dann hörst du auf und die zweite Shell läuft weiter.

Fenster und Schalen sind etwas unzusammenhängend. 

2
Fred Mitchell

Das sollte wohl ein Kommentar sein, aber da kann ich noch nicht ...

In Windows können Sie Folgendes tun:

subprocess.call('python bb.py', creationflags=subprocess.CREATE_NEW_CONSOLE)
1
DSM