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
|
|
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
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
|
rklm
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: Der Rest der Shebang-Zeile in einem Argument, Der Pfad zur Skriptdatei, 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 | #!/home/user/bin/args.sh foo bar
echo ja
|
Dann | $ ./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
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
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 :
| $ 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
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
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? | /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:
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.
|