Unterschied "#!/usr/bin/env python" und "$ python file.py"?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
siggi
User
Beiträge: 79
Registriert: Montag 29. Januar 2007, 14:22

Warum wirkt ein Mausklick auf eine Datei filename.py mit Magic Line "#!/usr/bin/env python" anders als der direkte Befehl im Terminal "~$ python filename.py"? Ich habe Ubuntu 12.04 mit Python2.7.3 als default. Wenn ich, als Beispiel, diese Testdatei, turtleRunTest.py:

Code: Alles auswählen

#!/usr/bin/env python
from turtle import Turtle, Screen
screen = Screen()
raw_input("hit <Enter> to finish")
im Dateibrowser (Nautilus) anklicke, geht blitzschnell was auf und zu, das war's.

Wenn ich im Terminal eingebe

Code: Alles auswählen

$ python turtleRunTest.py
ist alles ok, die Turtle-Screen öffnet sich, bleibt auf bis ich mit <Enter> im Terminal das Turtle-Grafikfenster schliesse.

Warum wirken diese beiden Modi, ein Python-Programm zu starten, so unterschiedlich und wie muss ich das Programm verändern, damit auch nach Klick auf filename.py alles offen bleibt?

Danke,
Gruss,

siggi
BlackJack

@siggi: Das hängt letztendlich davon ab was Nautilus genau macht wenn Du auf die Datei klickst.

Edit: Wie hättest Du den vorgehabt etwas einzugeben um das ``raw_input()`` zu ”beenden”?
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Also wenn ich Python per Doppelklicke öffne geht bei mir auch nie ein Terminal auf, nur GUI Programme und die auch nur bei ausführbaren Dateien (chmod +x). Ansonsten wird das Standardprogramm zur Dateiendung gewählt (XFCE).
siggi
User
Beiträge: 79
Registriert: Montag 29. Januar 2007, 14:22

Vorbemerkung: die Dateien sind natürlich executable!

@BlackJack:
Das hängt letztendlich davon ab was Nautilus genau macht wenn Du auf die Datei klickst.
Nein, mit Thunar(Xubuntu) ist es auch nicht anders, und warum bleibt dann das Fenster beim folgenden Programm offen (du erinnerst dich, du hast mir dabei geholfen):

Code: Alles auswählen

#!/usr/bin/env python2

# pylab_tan.py

import pylab as pl

yMin = -100; yMax = 100.0

pl.title('y = tan(x)', color='blue', fontsize=16, fontweight='bold')

x = pl.arange(-pl.pi, pl.pi, 1/(yMax*100))
y = pl.tan(x)
y[abs(y) > yMax] = pl.nan
pl.plot(x, y)
pl.ylim(yMin, yMax)
pl.xlim(-pl.pi, pl.pi)
#pl.xlim(1.565, 1.575)
pl.grid(True)

pl.show()
. Egal, ob ich im Dateibrowser nach Anklicken aus dem Menü entweder "Run" oder "Run im Terminal" wähle, das Tangensplot-Fenster und im zweiten Fall auch das Terminal bleibt offen und ich kann alles in Ruhe anschauen; ganz im Gegensatz zu meinem obigen Testprogramm. Ich glaube, das hat irgendwas mit Grafikprogrammen, denn mit dem matlib programm hier klappt's ja; habe mal irgenwann etwas von Subprozess gelesen, und dass da ein "main()" oder so was am Ende stehen müsse, sonst würde sich das Fenster schliessen - ich kenne mich da leider nicht so aus.

Es bleibt die Frage: warum klappt es mit "python filename.py" und nicht mit Anklick? Steht doch in jedem Python-Buch, dass man Programme auch durch Anklicken starten kann, wenn sie die Magic Line enthaten!
Edit: Wie hättest Du denn vor]gehabt etwas einzugeben um das ``raw_input()`` zu ”beenden”?
Die Frage verstehe ich nicht.
Gruss,

siggi
BlackJack

@siggi: Doch es hängt davon ab was Nautilus genau macht. Und Thunar. Und jede andere Software mit der Du das Programm „grafisch” durch anklicken startest. Das wird nicht vom System vorgegeben sondern von den Programmierern die die Anwendungen programmiert haben, die Dir ein Icon zum draufklicken anzeigen. Wenn Du da drauf klickst wird Code von *der* Anwendung ausgeführt, der letztendlich das Programm irgendwie startet. Anscheinend macht Thunar das gleiche oder zumindest etwas ähnliches wie Nautilus.

Bei dem Matplotlib bleibt das Fenster offen weil `show()` solange blockiert bis das Fenster geschlossen wurde.

Beim Turtle-Skript wird keine Hauptschleife aufgerufen sondern am Ende das `raw_input()` was dann zu der Frage führt die Du nicht verstehst: Wo denkst Du kommen die Daten her die man da eingeben kann, oder halt auch nicht. Es gibt ja kein Terminal, es sei denn Nautilus wurde von einem gestartet. Also muss es da keine offene Standardeingabe geben von der `raw_input()` lesen kann. Was dann vielleicht zu einem `IOError` führt wenn versucht wird aus einer geschlossenen Datei zu lesen und damit zum Programmabbruch bei der Zeile. Wäre zumindest eine mögliche Erklärung. Ob es das nun ist… keine Ahnung.
siggi
User
Beiträge: 79
Registriert: Montag 29. Januar 2007, 14:22

Vielleich liegt's an Ubuntu 12.04 und Nautilus?

Falls hier jemand mit einer anderen Linux-Distro als Ubuntu reinschaut, bitte mal das folgende Progrämmchen (es hat jetzt kein raw_input mehr) testen:

Code: Alles auswählen

#!/usr/bin/env python2
from turtle import Screen
import time
screen = Screen()
time.sleep(10)
Wenn ich das Programm mit "$ python filename.py" im Terminal starte, öffnet sich das Grafikfenster und bleibt 10 Sekunden offen.

Wenn ich das Programm im Dateibrowser-Fenster mit Maus-Klick starte, öffnet und schliesst sich was blitzschnell, egal ob ich "Run" oder "Run in terminal" im Kontextmenü wähle.

Danke,
Gruss,

siggi
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Das ganze sieht mir eher so aus, als ob eine Exception auftritt. Schau doch mal in die Datei `~/.xsession-errors` und falls dort nichts ist, pack den Code in einen `try` Block und logge selbst evtl auftretende Exceptions.
siggi
User
Beiträge: 79
Registriert: Montag 29. Januar 2007, 14:22

`~/.xsession-errors` : eine Fülle von Informationen! Allerdings ohne Zeit- und Datumsangaben. Kann ich denn `~/.xsession-errors` einfach löschen und dann sehen, was nach einer neuen Klick-Geschichte darinsteht?
Gruss,

siggi
BlackJack

@siggi: Mach ein Konsolenfenster auf und führe dort ``tail -f ~/.xsession-errors`` aus, dann siehst Du „live” was neues hinzukommt. Zum Beispiel wenn Du auf das Icon klickst.
siggi
User
Beiträge: 79
Registriert: Montag 29. Januar 2007, 14:22

@BlackJack: da kam nichts neues hinzu! Keine zusätzliche Fehlermeldung.

Ich hoffe ja, dass hier irgendwann mal jemand mit einer nicht-auf-Ubuntu-basierten Distro reinschaut (Fedora, OpenSuse,..). Würde mich mal interessieren, was da mit Klick passiert.
Gruss,

siggi
BlackJack

@siggi: Ich tippe ja weiterhin auf eine Ausnahme.

Was passiert denn eigentlich wenn Du das vom Terminal aus als Skript startest? Also nicht Python starten und das Skript übergeben, sondern tatsächlich das Skript *selbst* starten. Nicht ``$ python file.py`` sondern ``$ ./file.py``.
JohnDoe

siggi hat geschrieben:Ich hoffe ja, dass hier irgendwann mal jemand mit einer nicht-auf-Ubuntu-basierten Distro reinschaut (Fedora, OpenSuse,..). Würde mich mal interessieren, was da mit Klick passiert.
Jetzt nicht ausgehend von deinem Skript (und unter Verwendung von Nautilus): Skripte starten, laufen und beenden sich genau so, wie man es erwartet. Sogar die Shebang wird beachtet (erste Zeile).

Wie @BlackJack schon sagte: Was passiert, wenn du dein Skript via ./skriptname.py startest? Oder nimm doch mal ein einfaches Skript, welche nur etwas in eine Datei reinschreibt (damit man sieht dass es läuft) und fertig.
siggi
User
Beiträge: 79
Registriert: Montag 29. Januar 2007, 14:22

@BlackJack, @JohnDoe: danke für die Tipps. Ich habe jetzt eine, für mich überraschende, Lösung gefunden: einfach Tkinter(python2) oder tkinter (python3) importieren, z.B. mit Python 2.7.3:

Code: Alles auswählen

#!/usr/bin/env python2
import Tkinter
raw_input("hit <Enter>")
Anschliessend kann kommen, was will, z.B. wie hier "raw_input", es klappt mit dem Klich :)

Enstprechend geht's bei mir auch mit python3, natürlich mit den entsprechenden Änderungen.
Gruss,

siggi
BlackJack

@siggi: Ich frage mich ja weiterhin wie Du bei dem `raw_input()` etwas eingeben willst wenn Du es über einen Mausklick startest. Ich sehe da sinnlose Prozesse die laufen und die man nicht beenden kann.

Für die Turtle-Geschichte ist *die* Lösung das man die dafür vorgesehene Hauptschleife `turtle.mainloop()` aufruft. Oder die `exitonclick()`-Methode auf dem `Screen` falls das das gewünschte Verhalten produziert.

Deine ”Lösung” ist Voodoo. Denn erstens ist nicht geklärt warum es mit dem `raw_input()` nicht funktioniert hat, und nur das importieren von `Tkinter` kann keine Lösung sein. Dafür gibt es IMHO keine logische Erklärung.
Benutzeravatar
peterpy
User
Beiträge: 188
Registriert: Donnerstag 7. März 2013, 11:35

siggi hat geschrieben:
Falls hier jemand mit einer anderen Linux-Distro als Ubuntu reinschaut, bitte mal das folgende Progrämmchen (es hat jetzt kein raw_input mehr) testen:
Hallo Siggi,
ich nutze Mageia mit KDE und Dolphin.
Ich hab das Script in meinem home als test.py gespeichert und als ausführbar markiert.
Dolphin schlägt (in den Eigenschaften) schon Python 2.7 zum Öffnen vor.
Ein Doppelklick in Dolphin auf test.py öffnet das Turtle Fenster, nach 10 Sekunden schliesst es wieder.

Gruss
Peter
siggi
User
Beiträge: 79
Registriert: Montag 29. Januar 2007, 14:22

@Peter: Danke für's Testen!

@BlackJack:
* 1 * Deine frühere Frage:
Was passiert denn eigentlich wenn Du das vom Terminal aus als Skript startest? Also nicht Python starten und das Skript übergeben, sondern tatsächlich das Skript *selbst* starten. Nicht ``$ python file.py`` sondern ``$ ./file.py``.

Code: Alles auswählen

:~/Desktop/Tom$ ./turtleRunTestPy2.py
bash: ./turtleRunTestPy2.py: Permission denied
Wenn ich dagegen Programme mit z.B. import Tkinter so starte, ist alles ok
Ich frage mich ja weiterhin wie Du bei dem `raw_input()` etwas eingeben willst wenn Du es über einen Mausklick startest.
Ich habe das mal vor Jahren so gelernt, dass ich damit ein Terminalprogramm anhalten kann, ehe es sich schliesst; hat eigentlich bisher immer funktioniert

Wahrscheinlich habe ich einiges durcheinandergebracht auf meinem System, als ich mal wieder "gespielt" habe ohne genau zu wissen was ich tat :oops:
Edit: Ausserdem scheint es noch ziemlich viele Probleme mit Nautilus auf Ubuntu 64bit zu geben:
https://bugs.launchpad.net/ubuntu/+sour ... thon/+bugs
Gruss,

siggi
BlackJack

@siggi: Na wunderbar, das ist die Fehlermeldung die man bekommt wenn die Datei das „executable”-Bit in den Dateirechten nicht gesetzt hat. Was dann auch erklärt warum das nicht per Klick ausführbar ist, weil die Datei grundsätzlich nicht ausführbar ist. Hat also rein gar nichts mit irgendwelchen Importen zu tun. Nun ist meine Welt wieder in Ordnung. :-)
siggi
User
Beiträge: 79
Registriert: Montag 29. Januar 2007, 14:22

Es ist aber gesetzt! Meine Welt ist deshalb nicht in Ordnung!
Gruss,

siggi
BlackJack

@siggi: Für den Benutzer der das ausführen will?

Wie sieht denn die Ausgabe von ``ls -l ~/Desktop/Tom/turtleRunTestPy2.py`` aus?
siggi
User
Beiträge: 79
Registriert: Montag 29. Januar 2007, 14:22

@BlackJack: es ist schon ein bisschen wie Vodoo oder noch besser wie das "Wasser mit Erinnerungsvermögen", das mal vor Jahren durch die Presse ging. Heute abend, vorhin, hat es mal wieder geklappt mit dem Klick.
Hier mal eine Zusammenfassung von heute abend (werde es mal irgendwann wiederholen und sehen, was dann rauskommt. Interessant, dass Ubuntu und Xubuntu z.T. verschieden reagieren:

Ubuntu 12.04 64 bit
python: Python 2.7.3 (default, Sep 26 2013, 20:03:06)

Datei turtleRunTestPy2.py:

Code: Alles auswählen

#!/usr/bin/env python
print "Test"
raw_input("Enter")
*********************
executable: activated
*********************
-rwxrwxr-x turtleRunTestPy2.py
* 1 *
$ -rwxr-xr-x turtleRunTestPy2.py
./turtleRunTestPy2.py
Ausgabe im Terminal:
Test
Enter
---> klappt

* 2 *
$ python turtleRunTestPy2.py
Test
Enter
---> klappt

* 3 *
nach Eingabe von "python" im Terminal:
>>> execfile("turtleRunTestPy2.py")
Test
Enter
---> klappt

* 4 *
Nautilus:
Linker Mausklick klappt
Recht Maus > Open: klappt
Rechte Maus > Kontext: open with Python2 klappt nicht


***********************
executable: deactivated
***********************
-rw-rw-r-- turtleRunTestPy2.py

* 1 *
$ ./turtleRunTestPy2.py
bash: ./turtleRunTestPy2.py: Permission denied
---> klappt nicht

* 2 *
$ python turtleRunTestPy2.py
Test
Enter
---> klappt

* 3 *
nach Eingabe von "python" im Terminal
>>> execfile("turtleRunTestPy2.py")
Test
Enter
---> klappt

* 4 *
Nautilus:
Linker Mausklick klappt nicht
Rechte Maus > Kontext: open with python2 klappt nicht

Xubuntu 12.04 32 bit
python: Python 2.7.3 (default, Sep 26 2013, 20:08:41)

Datei turtleRunTestPy2.py:

Code: Alles auswählen

#!/usr/bin/env python
print "Test"
raw_input("Enter")
*********************
executable: activated
*********************
-rwxrwxr-x turtleRunTestPy2.py
* 1 *
$ ./turtleRunTestPy2.py
Test
Enter
---> klappt

* 2 *
$ python turtleRunTestPy2.py
Test
Enter
---> klappt

* 3 *
nach Eingabe von "python" im Terminal:
>>> execfile("turtleRunTestPy2.py")
Test
Enter
---> klappt

* 4 *
Thunar:
Linker Mausklick klappt klappt nicht
Rechte Maus > Kontext: open with Python(2.7) klappt


***********************
executable: deactivated
***********************
-rw-rw-r-- turtleRunTestPy2.py

* 1 *
$ ./turtleRunTestPy2.py
bash: ./turtleRunTestPy2.py: Permission denied
---> klappt nicht

* 2 *
$ python turtleRunTestPy2.py
Test
Enter
---> klappt

* 3 *
nach Eingabe von "python" im Terminal
>>> execfile("turtleRunTestPy2.py")
Test
Enter
---> klappt

* 4 *
Thunar:
Linker Mausklick klappt
Rechte Maus > Kontext: open with Python(2.7) klappt

Ich habe jetzt erst mal genug geforscht. Ein frohes Weihnachtsfest dir und allen, die noch vorbeischauen!
Gruss,

siggi
Antworten