ubuntuusers.de

Python: Programm wird nicht ausgeführt

Status: Ungelöst | Ubuntu-Version: Kubuntu 18.04 (Bionic Beaver)
Antworten |

Axel-Erfurt

Anmeldungsdatum:
18. Mai 2016

Beiträge: 1347

Und wenn Du /usr/bin/python3 benutzt?

/usr/bin/python3
Python 3.8.5 (default, Jul 28 2020, 12:59:40) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print('Test')
Test
>>> import sys
>>> print(sys.version)
3.8.5 (default, Jul 28 2020, 12:59:40) 
[GCC 9.3.0]
>>> 

michahe

(Themenstarter)

Anmeldungsdatum:
12. Dezember 2013

Beiträge: 857

Danke Axel-Erfurt, mein aktueller Code

#!/usr/usr/bin/python3
print('Test')
import sys
print(sys.version)

Der Aufruf und die Ausgabe:

$ python PY.py
Test
2.7.17 (default, Sep 30 2020, 13:38:04) 
[GCC 7.5.0]
$

$ python ./PY.py
Test
2.7.17 (default, Sep 30 2020, 13:38:04) 
[GCC 7.5.0]
$

$ python3 PY.py
Test
3.6.9 (default, Oct  8 2020, 12:12:24) 
[GCC 8.4.0]

M.E. entscheidet nur der Aufruf der .py, welche Python-Version genutzt wird.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11250

Wohnort: München

Und jetzt mal noch so:

./PY.py 

Axel-Erfurt

Anmeldungsdatum:
18. Mai 2016

Beiträge: 1347

#!/usr/usr/bin/python3

da ist ein /usr zuviel

michahe

(Themenstarter)

Anmeldungsdatum:
12. Dezember 2013

Beiträge: 857

Axel-Erfurt schrieb:

#!/usr/usr/bin/python3

da ist ein /usr zuviel

Sorry für meine Unachtsamkeit. Jetzt hab ich's korrigiert

#!/usr/bin/python3
print('Test')
import sys
print(sys.version)

Und die Ergebnisse:

$ python ./PY.py
Test
2.7.17 (default, Sep 30 2020, 13:38:04) 
[GCC 7.5.0]

$ python PY.py
Test
2.7.17 (default, Sep 30 2020, 13:38:04) 
[GCC 7.5.0]

$ python3 PY.py
Test
3.6.9 (default, Oct  8 2020, 12:12:24) 
[GCC 8.4.0]

Also war das doppelte /usr ohne Effekt.

Die Methode von seahawk1986

> ./PY.py

ergibt mit

#!/usr/bin/python3}
die Version 3.6.9, jedoch mit 
{{{#!/usr/bin/python

die Version 2.7.17. Ziemliches Durcheinander für mich ...

Axel-Erfurt

Anmeldungsdatum:
18. Mai 2016

Beiträge: 1347

michahe schrieb:

die Version 2.7.17. Ziemliches Durcheinander für mich ...

python PY.py startet das Script mit python2, deshalb ergibt es 2.7.17

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17605

Wohnort: Berlin

michahe schrieb:

Und die Ergebnisse:

 
$ python ./PY.py
$ python PY.py

Da rufst Du beide Male das Programm python auf mit dem Parameter PY.py, also einer Datei im aktuellen Verzeichnis. Das ./ vorneweg macht da keinen Unterschied - wo sonst sollte die Datei sein? Deswegen solltest Du das begreifen und in Zukunft weglassen und nie wieder probieren, ob es einen Unterschied macht (auf Windows vielleicht).

Aber wann braucht man ./Py.py denn überhaupt, und wieso? Wenn Du ein Programm aufrufst - das ist hier nicht PY.py sondern python - und dieses liegt nicht im Pfad (PATH), dann signalisierst Du, dass Du es über seinen Pfad aufrufen willst. Du könntest auch $PWD/PY.py aufrufen, aber ./ ist ja schneller getippt und einfacher.

Beim Aufruf python PY.py ist das Programm, das Du aufrufst, python. Welches, das kannst Du prüfen mit which python. Das Programm lädt dann Dein Skript PY.py so wie ein Malprogramm gimp mit gimp foo.png ein Bild läd. Dafür muss PY.py nicht ausführbar gemacht werden (chmod +x PY.py). Um es ausführbar zu machen brauchst Du das chmod-Kommando und einen Shebang .

Wenn das Skript python3 benötigt, dann schreib das auch in den Shebang, dafür ist er da. Wenn es wurscht ist, nur python.

Es kommen hier mehrere Dinge zusammen: Dateiberechtigungen, Pfade, der PATH, der Shebang. Für sich genommen sind alle leicht zu verstehen und das Zusammenspiel ist logisch. Bei längerer Linuxnutzung, v.a. als Programmierer und wenn man auf der Shell unterwegs ist, kommt man nicht drumrum das früher oder später zu lernen.

Unter Windows wird auch im aktuellen Verzeichnis geschaut, ob da ein Programm liegt, wenn man eins aufruft. Unter unixoiden Systemen ist das nicht üblich.

Ansonsten gibt es da auch einen PATH mit der gleichen Funktion - nur der Trenner ist nicht : sondern ;.

Wenn du PY.py ausführbar gemacht und via ./PY.py gestartet hast, dann verhält es sich genauso, wie wenn Du es mit dem Kommando, das im Shebang steht, gestartet hättest. Das Starten mit Doppelklick im Dateibrowser oder über einen Desktopstarter ist dann noch mal ein gesondertes Problem.

michahe

(Themenstarter)

Anmeldungsdatum:
12. Dezember 2013

Beiträge: 857

Danke, mir raucht der Kopf ...

Das ./PY.py hatte ich benutzt, weil seahawk1986 es hier vorgeschlagen hat. Meine Which-Ergebnisse:

$ which python
/usr/bin/python
$ which python3
/usr/bin/python3

Jetzt habe ich einen Test für alle Varianten gemacht:

#!/usr/bin/python
   python  PY.py --> 2.717
   python3 PY.py --> 3.6.9
   ./PY.py       --> 2.717
#!/usr/bin/python3
   python  PY.py --> 2.717
   python3 PY.py --> 3.6.9
   ./PY.py       --> 3.6.9
#!/usr/bin/env/python3
   python  PY.py --> 2.717
   python3 PY.py --> 3.6.9
   ,/PY.py       --> bash: ./PY.py: /usr/bin/env/python3: Defekter Interpreter: Ist kein Verzeichnis
#!/usr/bin/python3.6
   python  PY.py --> 2.717
   python3 PY.py --> 3.6.9
   ./PY.py       --> 3.6.9
#!/usr/bin/env/python3.6
   python  PY.py --> 2.717
   python3 PY.py --> 3.6.9
   ,/PY.py       --> bash: ./PY.py: /usr/bin/env/python3: Defekter Interpreter: Ist kein Verzeichnis
#!/KEINE
   python  PY.py --> 2.717
   python3 PY.py --> 3.6.9
   ,/PY.py       --> bash: ./PY.py: /usr/bin/env/python3: Defekter Interpreter: Ist kein Verzeichnis

Also Aufruf mit PYTHON3

  • entweder python3 PY.py # Shebang wurscht

  • oder./PY.py UND Shebang python3*

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13176

Ich glaube, Du machst es Dir zu kompliziert. Eigentlich ist es ganz einfach:

  • Wenn man python oder python3 ausführt und einen Dateinamen eines Python-Skriptes übergibt, dann führt der jeweilige Interpreter, den man gestartet hat, das Skript aus. Was in der Shebang-Zeile steht ist egal. Es ist ebenfalls egal, ob das Skript "x"-Berechtigung hat.

  • Wenn man eine Skriptdatei ausführbar macht, dann wird der Prozess ausgeführt, der in der Shebang-Zeile hinter dem "#!" steht (direkt oder mit einem Leerzeichen) und folgendes wird übergeben:

    1. Der Rest der Shebang-Zeile in einem Argument,

    2. Der Pfad zur Skriptdatei,

    3. Alle weiteren beim Aufruf übergebenen Argumente jeweils einzeln.

Da es auf Deinem System kein /usr/bin/env/python3.6 gibt, führt das natürlich zu einem Fehler. Da müsste ein Leerzeichen statt dem Slash zwischen "env" und "python3.6" stehen. Die letzte Fehlermeldung passt übrigens nicht dazu, dass da angeblich keine Shebang-Zeile war.

Wenn man /usr/bin/env als Prozess in der Shebang-Zeile angibt, dann wird der ausgeführt und erhält Argumente, wie oben beschrieben. Nun ist es das Verhalten von env die weiteren Argumente, die ein Gleichheitszeichen enthalten, als Variablenzuweisungen zu betrachten die in einer neuen Umgebung ausgeführt werden und das erste folgende Argument als Prozess, der nach ggf. Suche in $PATH ausgeführt wird. Details in der Manpage von env.

Wenn Du das Skript von meiner Benutzerseite in eine Datei args.sh packst und die als Shebang nutzt, kannst Du das selber ausprobieren z.B. mit

1
2
3
#!/home/user/bin/args.sh foo bar

echo ja

Dann

1
2
3
4
5
6
7
$ ./x 11 22 '33 44'
5 args
arg[1]: <foo bar>
arg[2]: <./x>
arg[3]: <11>
arg[4]: <22>
arg[5]: <33 44>

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13176

michahe schrieb:

Meine Which-Ergebnisse:

$ which python
/usr/bin/python
$ which python3
/usr/bin/python3

Randbemerkung: im 21. Jahrhundert sollte man type statt which benutzen, denn das ist ein Shell-Builtin, das selbst die sh kennt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ which which
/usr/bin/which
$ which type
$ type which
which is /usr/bin/which
$ type type
type is a shell builtin
$ which ls
/bin/ls
$ type ls
ls is aliased to `ls --color=auto -F'
$ type -a ls
ls is aliased to `ls --color=auto -F'
ls is /bin/ls

Vor allem in Zeilen 9 und 11 siehst Du das Problem von which.

Neral

Anmeldungsdatum:
3. Oktober 2007

Beiträge: 230

Randbemerkung zur Randbemerkung: Im 21. Jahrhundert sollte man nicht davon ausgehen, dass die ganze Welt bash benutzt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ which which
which: shell built-in command
$ which type
type: shell built-in command
$ type which
which is a shell builtin
$ type type
type is a shell builtin
$ which ls
ls: aliased to ls --color=tty
$ type ls
ls is an alias for ls --color=tty
$ type -a ls
ls is an alias for ls --color=tty
ls is /usr/bin/ls
ls is /bin/ls

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13176

Neral schrieb:

Randbemerkung zur Randbemerkung: Im 21. Jahrhundert sollte man nicht davon ausgehen, dass die ganze Welt bash benutzt:

Bin ich nicht. Welche Shell hast Du denn verwendet?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ which which
which: shell built-in command
$ which type
type: shell built-in command
$ type which
which is a shell builtin
$ type type
type is a shell builtin
$ which ls
ls: aliased to ls --color=tty
$ type ls
ls is an alias for ls --color=tty
$ type -a ls
ls is an alias for ls --color=tty
ls is /usr/bin/ls
ls is /bin/ls

Die Ausgaben zeigen ja, dass type allgemeiner ist, was auch nicht verwundert, weil es POSIX-Standard ist, während which das nicht ist.

Neral

Anmeldungsdatum:
3. Oktober 2007

Beiträge: 230

@rklm: zsh.

Die Ausgaben zeigen ja, dass type allgemeiner ist

Naja, which kann auch -a:

1
2
3
4
$ which -a ls
ls: aliased to ls --color=tty
/usr/bin/ls
/bin/ls

(Beides ist in zsh ein Alias für whence.)

Ist es sinnvoll, sich auf POSIX zu beschränken? In diesem Kontext, also nicht in Shellskripten, die man vielleicht auch mal auf einem anderen System nutzen will?

Python ist auch nicht im POSIX-Standard. Sollte man es deswegen nicht benutzen? Was ist mit type -a? Das ist auch kein POSIX, weil type laut Standard keine Optionen hat.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13176

Neral schrieb:

@rklm: zsh.

Die Ausgaben zeigen ja, dass type allgemeiner ist

Naja, which kann auch -a:

Darum geht es mir nicht. type wird von mehr Shells unterstützt.

Ist es sinnvoll, sich auf POSIX zu beschränken?

Zumindest so lange, wie Dinge dadurch nicht unnötig umständlich werden. Wenn ich mir merke type nutzt man zum finden eines Kommandos, ist das genau so viel Aufwand wie which - nur, dass halt letzteres in weniger Situationen gut funktioniert. Aber wir sind hier mittlerweile offtopic.

Python ist auch nicht im POSIX-Standard. Sollte man es deswegen nicht benutzen?

s.o.

Was ist mit type -a? Das ist auch kein POSIX, weil type laut Standard keine Optionen hat.

Ja, und? Ich bin da pragmatisch und nicht ideologisch. s.o.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17605

Wohnort: Berlin

Aber python, weder python2, noch python3 sind Shellbuiltins (vielleicht in einer Pythonshell?).

Wichtig wäre

a) den Wikiartikel Shebang in Ruhe zu lesen und zu verstehen zu versuchen b) Fehlermeldungen zu lesen

,/PY.py –> bash: ./PY.py: /usr/bin/env/python3: Defekter Interpreter: Ist kein Verzeichnis

Wer wie wo was ist ein defekter Interpreter? Wolltest Du einen Interpreter aufrufen? Was ist ein Dateipfad? Was ist ein Kommandoaufruf?

1
2
3
/usr/bin/python py.py
/usr/bin/env python
./py.py

Hier siehst Du 3 Kommandos.

Das erste ist ein Aufruf des Programms "python" mit dem Parameter "py.py". Dafür muss py.py nicht ausführbar sein - es ist so wie "gimp py.png" oder "vlc py.wav" - Programmaufruf und Datei mit Daten. Semantisch gesehen sind die Daten selbst wieder ein Programm, aber hier sind es Daten, die "python" verarbeiten soll.

Dagegen "env python" ruft das Programm "env" auf, und das kannst Du Anfangs getrost ignorieren. Das mag interessant sein, wenn Du ein Skript für verschiedene Unixplattformen verteilst, also nächstes Jahr, vielleicht. Hier ist "python" das Argument und das Programm env schaut, wo python installiert ist, um es dann aufzurufen, wenn es sich hier um eine Shebangzeile handelt. Mehr verrät die Manpage (man env).

Das dritte ist der direkte Aufruf des Programms. Damit das funktioniert muss das Programm:

  • einen Shebang haben (einen funktionierenden)

  • ausführbar gemacht worden sein.

Du warst kurz davor und hast Dich auf den Pfad des "env" locken lassen. Schreib da den Pfad zu Python rein - der Version, die Du aufrufen willst, wenn es eine spezielle ist, prüfe ob der Pfad stimmt, der Shebang funktioniert, fertig.

Manche User sind ganz stolz, wenn sie env entdeckt und begriffen haben, und empfehlen es jedem Rookie. Lasst doch die Leute in kleinen Schritten lernen, wenn es geht immer nur eine Sache auf einmal.