Kiedy używam shebang #!/usr/bin/env python
do uruchamiania skryptu, skąd system wie, którego python
użyć? jeśli szukam python
ścieżki bin w zmiennych środowiskowych, nic nie znajduję.
env | grep -i python
Kiedy używam shebang #!/usr/bin/env python
do uruchamiania skryptu, skąd system wie, którego python
użyć? jeśli szukam python
ścieżki bin w zmiennych środowiskowych, nic nie znajduję.
env | grep -i python
Odpowiedzi:
Shebang oczekuje użycia pełnej ścieżki do interpretera, więc następująca składnia byłaby niepoprawna:
#!python
Ustawienie pełnej ścieżki w ten sposób może działać:
#!/usr/local/bin/python
ale byłoby non przenośny jak pyton mogą być instalowane w /bin
, /opt/python/bin
lub gdziekolwiek inną lokalizację.
Za pomocą env
#!/usr/bin/env python
jest metodą pozwalającą przenośnemu sposobowi na określenie w systemie operacyjnym pełnej ścieżki równoważnej ścieżce, w której python
najpierw znajduje się on w systemie PATH
.
Linia shebang (z „ostrego huku”, tj. #!
) Jest przetwarzana przez jądro. Jądro nie chce wiedzieć o zmiennych środowiskowych, takich jak PATH
. Zatem nazwa w linii shebang musi być bezwzględną ścieżką do pliku wykonywalnego. Możesz także podać dodatkowy argument, który zostanie przekazany do tego pliku wykonywalnego przed nazwą skryptu (z ograniczeniami zależnymi od systemu, nie wchodzę tutaj). Na przykład w przypadku skryptu w języku Python można określić
#!/usr/bin/python
w pierwszym wierszu i po uruchomieniu skryptu jądro faktycznie się uruchomi /usr/bin/python /path/to/script
. Ale to nie jest wygodne: musisz podać pełną ścieżkę polecenia. Co jeśli python
w /usr/bin
niektórych maszynach i /usr/local/bin
na innych? Czy chcesz, aby ustawić PATH
się /home/joe/opt/python-2.5/bin
tak, aby użyć określonej wersji Pythona? Ponieważ jądro nie PATH
wyszukuje za ciebie, chodzi o to, aby jądro uruchomiło polecenie, które z kolei szuka żądanego interpretera w PATH
:
#!/fixed/path/to/path-lookup-command python
To path-lookup-command
musi przyjąć nazwę pliku wykonywalnego jako argument, wyszukać go PATH
i wykonać: jądro będzie działać /fixed/path/to/path-lookup-command python /path/to/script
. Tak się składa, że env
polecenie właśnie to robi. Jego głównym celem jest uruchomienie komendy w innym środowisku, ale ponieważ szuka ona nazwy komendy $PATH
, jest idealna do naszego celu tutaj.
Chociaż nie jest to oficjalnie zagwarantować, historyczne systemy Unix przewidziane env
w /usr/bin
oraz nowoczesne systemy zachowali tę lokalizację właśnie ze względu na powszechne stosowanie #!/usr/bin/env
. Tak więc w praktyce można określić, że skrypt musi zostać wykonany przez ulubionego interpretera języka Python
#!/usr/bin/env python
env
a which
? od którego otrzymam również najbardziej odpowiedni plik wykonywalny z mojego środowiska PATH.
which
znajduje plik wykonywalny i drukuje jego ścieżkę. env
znajduje program określony przez pierwszy argument i wykonuje go, przekazując mu pozostałe argumenty.
env
wersja ewaluacyjna which
.
Racja, więc uruchom:
env | grep PATH
Twoja $ PATH to lista katalogów. Unix będzie przeglądał tę listę katalogów w kolejności, aż znajdzie „python”.
Możesz sprawdzić, który katalog znajduje, za pomocą polecenia „which”:
which python
sys.path
między aktywowaną env $ env python3
( ['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/.local/lib/python3.4/site-packages', '/usr/lib/python3.4/site-packages', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
) i ./env/bin/python3
(['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/test/env3/lib/python3.4/site-packages']
).