Widziałem w wielu miejscach, w tym w zaleceniach na tej stronie ( jaki jest preferowany shebang Bash? ), Których należy używać #!/usr/bin/env bash
przed #!/bin/bash
. Widziałem nawet jedną przedsiębiorczą osobę, która sugerowała, że użycie #!/bin/bash
było złe i funkcjonalność basha zostałaby utracona.
To powiedziawszy, używam bash w ściśle kontrolowanym środowisku testowym, w którym każdy dysk w obiegu jest zasadniczo klonem pojedynczego dysku głównego. Rozumiem argument dotyczący przenośności, choć niekoniecznie ma on zastosowanie w moim przypadku. Czy istnieje jakikolwiek inny powód, aby preferować #!/usr/bin/env bash
alternatywne rozwiązania, a przy założeniu, że problemem była przenośność, czy istnieje jakiś powód, dla którego można by ją zepsuć?
env
może nie znajdować się w/usr/bin
. Komentarze Shebang są złym pomysłem IMHO. Jeśli domyślny interpreter skryptów nie obsługuje komentarzy shebang, jest to tylko komentarz. Jeśli jednak wiesz, że interpreter skryptu może obsłużyć komentarze shebang i znasz ścieżkę do bashu, nie ma powodu, aby nie wywoływać go przy użyciu jego ścieżki bezwzględnej, chyba że ścieżka jest za długa (mało prawdopodobna), lub możesz przenieść skrypt do systemu, w którym bash nie znajduje się w / bin. Z drugiej strony, wcześniej wspomniane zastrzeżenia mają zastosowanie w tym przypadku, ponieważ wiąże się z przenośnością./etc
lub/bin/sh
.bash
jest dodatkiem do większości systemów uniksowych. Tylko Linuxbash
jest gwarantowany/bin
i najprawdopodobniej również jako/bin/sh
. Odkąd Linux stał się nowoczesnym de facto Uniksem dla wielu ludzi, zapomniano o istnieniu systemów innych niż Linux. W mojej własnej odpowiedzi poniżej założyłem Linuxa, ponieważ tak powiedziałeśbash
. Wiele urządzeń BSD, z którymi pracowałem, nawet nie ma zainstalowanych./bin/bash
. Bash nie jest domyślnie instalowany. Jeśli chcesz, musiszpkg install bash
. Po zainstalowaniu znajduje się pod adresem/usr/local/bin/bash
. Na/bin/bash
OpenBSD nie ma nic zainstalowanego . Szereg#!/bin/bash
woli popełni błąd i#!/usr/bin/env bash
odniesie sukces.Odpowiedzi:
#!/usr/bin/env
wyszukiwaniaPATH
dlabash
, abash
nie zawsze jest/bin
, szczególnie w systemach innych niż Linux. Na przykład w moim systemie OpenBSD jest on włączony/usr/local/bin
, ponieważ został zainstalowany jako opcjonalny pakiet.Jeśli jesteś absolutnie pewien, że
bash
jest/bin
i zawsze będzie, umieszczenie go bezpośrednio w swoim shebang nie zaszkodzi - ale odradzam to, ponieważ skrypty i programy mają życie dłuższe niż początkowo sądzimy, że będą.źródło
env
lokalizacją? POSIX tego nie wymusza./usr/lib/sendmail
(lub ostatnio/usr/sbin/sendmail
) pliku binarnego dostępnego do przetwarzania poczty, leży to w najlepszym interesie systemu uniksowego,/usr/bin/env
ponieważ shevang env jest tak powszechną praktyką. Jest to de facto standardowy interfejs.env
, ale jakoś nie mieć standardowej lokalizacji (która może być tylko miękkim linkiem)bash
. Nie wspominając już o tym, dlaczego hashbang nie akceptuje tylko#!bash
i używaPATH
, zamiast robić dokładnie to samo zenv
. Chyba nie dość mylące dla początkujących.This mostly works because the path /usr/bin/env is commonly used for the env utility
tutaj en.wikipedia.org/wiki/Shebang_(Unix) - Musimy zwierzyć się zenv
bycia tam „prawdopodobnie” we wszystkich systemach.env
był/bin
, a nie w/usr/bin
(nie jestem pewien, który to prawdopodobnie SunOS 4). W dzisiejszych czasach jest bardzo prawdopodobne,/usr/bin/env
że będzie dostępny, tylko ze względu na popularność#!/usr/bin/env
hacka.Standardowa lokalizacja bash to
/bin
i podejrzewam, że tak jest we wszystkich systemach. Co jednak, jeśli nie spodoba ci się ta wersja bash? Na przykład chcę użyć wersji bash 4.2, ale wersja bash na moim komputerze Mac to 3.2.5.Mógłbym spróbować ponownie zainstalować bash,
/bin
ale to może być zły pomysł. Jeśli zaktualizuję system operacyjny, zostanie on zastąpiony.Mogę jednak zainstalować bash
/usr/local/bin/bash
i skonfigurować ŚCIEŻKĘ do:Teraz, jeśli sprecyzuję
bash
, nie dostanę starego, szorstkiego/bin/bash
, ale nowszego, bardziej błyszczącego/usr/local/bin
. Miły!Tyle że moje skrypty powłoki mają ten
!# /bin/bash
shebang. Tak więc, kiedy uruchamiam skrypty powłoki, otrzymuję starą i kiepską wersję basha, która nawet nie ma tablic asocjacyjnych.Użycie
/usr/bin/env bash
spowoduje użycie wersji bash z mojej ŚCIEŻKI. Jeśli skonfiguruję ŚCIEŻKĘ, to tak/usr/local/bin/bash
została wykonana, to będzie bash, którego użyją moje skrypty.Rzadko widuje się to podczas bash, ale jest znacznie bardziej powszechne w Perlu i Pythonie:
/bin
?/usr/bin
?/opt/bin
? Kto wie? Używanie#! /usr/bin/env perl
oznaczało, że nie musiałem wiedzieć.A teraz dlaczego nie powinieneś używać
#! /usr/bin/env bash
Kiedy ścieżka jest zakodowana na sztywno, muszę biec z tym tłumaczem. W ten sposób
#! /bin/bash
zmusza mnie do korzystania z zainstalowanego domyślną wersję bash. Ponieważ funkcje bash są bardzo stabilne (spróbuj uruchomić wersję 2.x skryptu Python pod Pythonem 3.x), jest bardzo mało prawdopodobne, że mój konkretny skrypt BASH nie będzie działał, a ponieważ mój skrypt bash jest prawdopodobnie używany przez ten system i inne systemy , używanie niestandardowej wersji bash może mieć niepożądane skutki. Jest bardzo prawdopodobne, że chcę się upewnić, że w moim skrypcie powłoki używana jest stabilna standardowa wersja bash. Dlatego prawdopodobnie chcę mocno zakodować ścieżkę w moim shebang.źródło
Przywoływanie
bash
to trochę przesada. Chyba że masz wielebash
plików binarnych, takich jak twój własny w ~ / bin, ale oznacza to również, że twój kod zależy od tego, czy $ PATH ma w sobie odpowiednie rzeczy.Jest to przydatne przy takich rzeczach
python
. Istnieją skrypty opakowania i środowiska, które prowadzą dopython
użycia alternatywnych plików binarnych.Ale nic nie jest stracone przez zastosowanie dokładnej ścieżki do pliku binarnego, o ile masz pewność, że jest to plik binarny, którego naprawdę potrzebujesz.
źródło
python
. Straciłem liczbę miejsc, którepython
można znaleźć 😀/usr/bin/env
jest to bardziej przydatne dla Pythona, szczególnie jeśli używasz virtualenv.Istnieje wiele systemów, które nie zawierają Bash
/bin
, FreeBSD i OpenBSD, żeby wymienić tylko kilka. Jeśli twój skrypt ma być przenośny dla wielu różnych Uniksów, możesz użyć#!/usr/bin/env bash
zamiast niego#!/bin/bash
.Zauważ, że nie dotyczy to
sh
; Bourne skryptów zgodnych I wyłącznie używać#!/bin/sh
, ponieważ myślę, że prawie każdy ma Unix istniejesh
w/bin
.źródło
/bin
Widzę w Ubuntu 18.04 reżsh -> dash
. Symbolicznie powiązany zdash
, ujawniając naturę Debiana Ubuntu. Uruchomić te trzy ciągi poleceń, aby uświadomić sobie, że wszystko sprowadza się do indywidualnych preferencji:which bash
wtedywhich sh
potemwhich dash
.Wolałbym zawinąć główny program w skrypt jak poniżej, aby sprawdzić wszystkie
bash
dostępne w systemie. Lepiej mieć większą kontrolę nad wersją, której używa.źródło
jest zdecydowanie lepszy, ponieważ znajduje ścieżkę wykonywalną bash ze zmiennej środowiskowej systemu.
Przejdź do powłoki Linux i wpisz
Wydrukuje wszystkie zmienne środowiskowe.
Przejdź do skryptu powłoki i wpisz
Spowoduje to wydrukowanie ścieżki bash (zgodnie z listą zmiennych środowiskowych), której należy użyć do zbudowania poprawnej ścieżki shebang w skrypcie.
źródło