Nagłówek skryptu Python

79

Powinien mieć typowy nagłówek

#!/usr/bin/env python

Ale okazało się, że poniżej działa również podczas wykonywania skryptu, takiego jak $python ./my_script.py

#!/usr/bin/python
#!python

Jaka jest różnica między tymi dwoma nagłówkami? Jaki może być problem z drugim? Proszę również omówić przypadek, w którym interpreter Pythona jest w PATH lub nie. Dzięki.

Stan
źródło
3
ten nagłówek nazywa się Shebang en.wikipedia.org/wiki/Shebang_%28Unix%29
systempuntoout
4
Do Twojej wiadomości, kiedy uruchamiasz skrypt w ten sposób $ python ./my_script.py(określając pythonjawnie), #!wiersz shebang ( ) jest ignorowany. Działa to tylko wtedy, gdy uruchomisz skrypt jako plik wykonywalny, np $ ./my_script.py.
David Z
@David Zaslavsky: +1 Dobry chwyt.
Mark Byers

Odpowiedzi:

103

Po pierwsze, za każdym razem, gdy uruchamiasz skrypt przy użyciu interpretera jawnie, jak w

$ python ./my_script.py
$ ksh ~/bin/redouble.sh
$ lua5.1 /usr/local/bin/osbf3

#!linia jest zawsze ignorowane. #!Linia jest cechą Unix wykonywalnych tylko skrypty, i widać to w pełni udokumentowane na stronie manexecve(2) . Tam zobaczysz, że następujące po nim słowo #!musi być ścieżką do prawidłowego pliku wykonywalnego. Więc

#!/usr/bin/env python

wykonuje wszystko, co pythonjest na użytkownikach $PATH. Ta forma jest odporna na przenoszenie interpretera Pythona, co sprawia, że ​​jest nieco bardziej przenośna, ale oznacza również, że użytkownik może zastąpić standardowy interpreter Pythona, umieszczając coś przed nim $PATH. W zależności od twoich celów to zachowanie może być w porządku lub nie.

Kolejny,

#!/usr/bin/python

zajmuje się typowym przypadkiem, w którym jest zainstalowany interpreter języka Python /usr/bin. Jeśli jest zainstalowany gdzie indziej, tracisz. Ale jest to dobry sposób, aby upewnić się, że otrzymasz dokładnie taką wersję, jaką chcesz, lub w ogóle nic (zachowanie „zatrzymania awaryjnego”), jak w

#!/usr/bin/python2.5

Wreszcie,

#!python

działa tylko wtedy, gdy pythonw bieżącym katalogu znajduje się plik wykonywalny, gdy skrypt jest uruchamiany. Niepolecane.

Norman Ramsey
źródło
28


Proponuję 3 rzeczy na początku twojego scenariusza:

Po pierwsze, jak już zostało powiedziane, użyj środowiska:

#!/usr/bin/env python

Po drugie, ustaw kodowanie:

# -*- coding: utf-8 -*-

Po trzecie, ustaw dokumentację:

"""This is a awesome
    python script!"""

I na pewno użyłbym " "(4 spacje) dla ident.
Końcowy nagłówek będzie wyglądał następująco:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""This is a awesome
        python script!"""


Najlepsze życzenia i szczęśliwego kodowania.

Dimitar Atanasov
źródło
Aby wesprzeć pozornie uparty komentarz dotyczący spacji nad tabulatorami: „Spacje są preferowaną metodą wcięć”. ( python.org/dev/peps/pep-0008/#tabs-or-spaces )
deepelement
5

Plik wykonywalny Pythona może być zainstalowany w lokalizacji innej niż / usr / bin, ale envprawie zawsze jest obecny w tej lokalizacji, więc używanie /usr/bin/envjest bardziej przenośne.

Mark Byers
źródło
2

Ze strony podręcznika env(GNU coreutils 6.10):

env - run a program in a modified environment

Teoretycznie można użyć envdo zresetowania środowiska (usunięcie wielu istniejących zmiennych środowiskowych) lub dodania dodatkowych zmiennych środowiskowych w nagłówku skryptu. Praktycznie rzecz biorąc, obie wspomniane przez Ciebie wersje są identyczne. (Chociaż inni wspominali o dobrym punkcie: określenie pythonprzez envpozwala abstrakcyjnie określić pythonbez znajomości ścieżki).

Annika Backstrom
źródło
1

Tak, jest - pythona może nie być /usr/bin, ale na przykład w /usr/local/bin(BSD).

Podczas korzystania z virtualenv może to być nawet coś takiego ~/projects/env/bin/python

Almad
źródło
0

/usr/bin/env pythonStaje się bardzo przydatny, gdy skrypty zależą od ustawień środowiska na przykład za pomocą skryptów, które opierają się na python virtualenv. Każdy virtualenv ma własną wersję pliku binarnego Pythona, która jest wymagana do dodawania pakietów zainstalowanych w virtualenv do ścieżki języka Python (bez dotykania PYTHONPATH env).

Ponieważ coraz więcej osób zaczęło używać virtualenv do programowania w Pythonie, wolą używać, /usr/bin/env pythonchyba że nie chcesz, aby ludzie używali ich niestandardowego pliku binarnego Pythona.

Uwaga: należy również zrozumieć, że istnieją potencjalne problemy z bezpieczeństwem (w środowiskach wielu użytkowników), gdy zezwalasz ludziom na uruchamianie skryptów w ich niestandardowych środowiskach. Można uzyskać kilka pomysłów tutaj .

Jatin Kumar
źródło