A kiedy zaczniesz przeglądać profile Apparmor, zobaczysz #include. Tam też #nie jest to komentarz.
4
@ vasa1 Ale kluczowym punktem, który często nie jest doceniany w wierszach hashbanga na początku skryptów powłoki, jest to, że są komentarzami .
Eliah Kagan
Odpowiedzi:
100
#!Linia jest używana przed prowadzony jest skrypt, a następnie ignorowane , gdy skrypt jest uruchamiany.
Pytasz, jaka jest różnica między linią shebang a zwykłym komentarzem.
Linia zaczynająca się od #!jest tak samo komentarzem jak każda inna linia zaczynająca się od #. Dzieje się tak, jeśli #!jest to pierwszy wiersz pliku lub gdziekolwiek indziej. #!/bin/shma efekt , ale nie jest odczytywany przez samego tłumacza .
#nie jest komentarzem we wszystkich językach programowania, ale, jak wiecie, jest komentarzem w powłokach w stylu Bourne'a, w tym shi bash(a także w większości takich powłok csh). To także komentarz w Pythonie . Jest to komentarz w wielu plikach konfiguracyjnych, które wcale nie są skryptami (jak /etc/fstab).
Załóżmy, że skrypt powłoki zaczyna się od #!/bin/sh. To jest komentarz, a tłumacz (powłoka) ignoruje wszystko w wierszu po #znaku.
Celem #!linii nie jest udzielanie informacji tłumaczowi. Celem tego #!wiersza jest poinformowanie systemu operacyjnego (lub innego procesu uruchamiającego interpreter), co ma być używane jako interpreter .
Jeśli skrypt zostanie wywołany jako plik wykonywalny, na przykład przez uruchomienie ./script.sh, system przejdzie do pierwszego wiersza, aby sprawdzić, czy zaczyna się od #!, po którym następuje zero lub więcej spacji, a następnie polecenie. Jeśli tak, uruchamia to polecenie z nazwą skryptu jako argumentu. W tym przykładzie działa /bin/sh script.sh(lub technicznie /bin/sh ./script.sh).
Jeśli skrypt zostanie wywołany przez jawne wywołanie interpretera, #!linia nigdy nie zostanie sprawdzona. Więc jeśli uruchomisz sh script.sh, pierwsza linia nie ma wpływu. Jeśli script2.shpierwszym wierszem jest #!/usr/games/nibbles, uruchomienie sh script2.shnie spróbuje otworzyć skryptu w nibbles(ale ./script2.shzrobi).
Zauważysz, że w żadnym przypadku rozszerzenie skryptu ( .sh), jeśli takie posiada, nie wpływa na sposób jego działania. W systemie uniksowym zwykle nie wpływa to na sposób uruchamiania skryptu. W niektórych innych systemach, takich jak Windows, #!linia shebang może być całkowicie ignorowana przez system, a rozszerzenie może określać, co uruchamia skrypty. (Nie oznacza to, że musisz podawać rozszerzenia skryptów, ale jest to jeden z powodów, dla których tak robisz, powinny być poprawne).
#!został wybrany, aby służyć temu celowi właśnie dlatego , że# zaczyna się komentarz. #!Linia jest w systemie, a nie tłumacz, i powinno być ignorowane przez interpreter.
Linia Shebang dla skryptów Bash
Ty (pierwotnie) powiedział użyć #!/bin/shdla bashskryptów. Powinieneś to zrobić tylko wtedy, gdy skrypt nie wymaga żadnego z bashrozszerzeń - shmusi być w stanie uruchomić skrypt. shnie zawsze jest dowiązaniem symbolicznym do bash. Często, w tym na wszystkich ostatnio zdalnych systemach Debian i Ubuntu , shjest dowiązaniem symbolicznym dash.
Linia Shebang dla skryptów Python
Powiedziałeś także (w pierwszej wersji swojego pytania, przed edycją), że uruchamiasz skrypty Pythona #!/bin/sh read by the interpretor. Jeśli masz na myśli dosłownie, zdecydowanie powinieneś przestać to robić. Jeśli hello.pyzaczyna się od tej linii, uruchamianie ./hello.pywykonuje:
/bin/sh read by the interpretor hello.py
/bin/shspróbuje wykonać skrypt o nazwie read(ze by the interpretor hello.pyswoimi argumentami), read(miejmy nadzieję) nie zostanie znaleziony, a twój skrypt w Pythonie nigdy nie będzie widoczny dla interpretera Pythona.
Jeśli popełniasz ten błąd, ale nie mam problemu, który opisuję, prawdopodobnie python hello.pywywołujesz skrypty Pythona, jawnie określając interpreter (np. ), Co powoduje zignorowanie pierwszej linii. Kiedy dystrybuujesz swoje skrypty innym osobom lub używasz ich przez długi czas później, może nie być jasne, że jest to konieczne do ich działania. Najlepiej je teraz naprawić. Lub przynajmniej całkowicie usuń pierwszy wiersz, aby w przypadku niepowodzenia uruchomienia ./komunikat o błędzie miał sens.
W przypadku skryptów w języku Python, jeśli wiesz, gdzie jest (lub będzie) interpreter języka Python, możesz napisać #!wiersz w ten sam sposób:
Problem polega jednak na tym, że chociaż /bin/shpowinien istnieć zawsze i /bin/bashprawie zawsze istnieje w systemach bashz systemem operacyjnym, Python może istnieć w różnych miejscach.
Dlatego wielu programistów Python używa tego zamiast tego:
#!/usr/bin/env python
(Lub #!/usr/bin/env python3dla Python 3.)
To sprawia, że skrypt polega na envbyciu w „właściwym miejscu” zamiast na pythonbyciu we właściwym miejscu. To dobrze, ponieważ:
envprawie zawsze znajduje się w /usr/bin.
W większości systemów, w zależności od tego, który skrypt pythonpowinien zostać uruchomiony, jest ten, który pojawia się jako pierwszy w PATH. Począwszy hello.pyod #!/usr/bin/env pythonmake ./hello.pyrun /usr/bin/env python hello.py, który jest (praktycznie) równoważny z bieganiem python hello.py.
Nie możesz użyć #!pythontego, że:
Chcesz, aby określony interpreter był podawany przez ścieżkę bezwzględną (tzn. Zaczynając od /).
Proces wywoływania byłby wykonywany pythonw bieżącym katalogu . Przeszukiwanie ścieżki, gdy polecenie nie zawiera ukośnika, jest specyficznym zachowaniem powłoki.
Czasami Python lub inny skrypt, który nie jest skryptem powłoki, będzie miał linię shebang zaczynającą się od miejsca, w #!/bin/sh ...którym ...znajduje się inny kod. Czasami jest to poprawne, ponieważ istnieją pewne sposoby wywołania powłoki ( sh) Bourne'a zgodnej z argumentami, aby wywołać interpreter Pythona. (Jeden z argumentów prawdopodobnie będzie zawierał python.) Jednak dla większości celów #!/usr/bin/env pythonjest prostszy, bardziej elegancki i bardziej prawdopodobne, że będzie działał tak, jak chcesz.
Linie Shebang w innych językach
Wiele języków programowania i skryptów oraz niektóre inne formaty plików służą #jako komentarz. Dla każdego z nich plik w języku może być uruchomiony przez program, który bierze go jako argument, określając program w pierwszym wierszu po #!.
W niektórych językach programowania #zwykle nie jest komentarzem, ale jako szczególny przypadek pierwszy wiersz jest ignorowany, jeśli zaczyna się od #!. Ułatwia to użycie #!składni, nawet jeśli w #innym przypadku nie czyni komentarza wierszem.
Linie Shebang dla plików, które nie działają jako skrypty
Chociaż jest to mniej intuicyjne, każdy plik, którego format pliku może pomieścić pierwszą linię rozpoczynającą się od #!następnej pełnej ścieżki pliku wykonywalnego, może mieć linię shebang. Jeśli to zrobisz, a plik zostanie oznaczony jako wykonywalny, możesz uruchomić go jak program ... powodując jego otwarcie jak dokument.
Niektóre aplikacje używają tego zachowania celowo. Na przykład w VMware .vmxpliki definiują maszyny wirtualne. Możesz „uruchomić” maszynę wirtualną tak, jakby to był skrypt, ponieważ pliki te są oznaczone jako pliki wykonywalne i mają linię shebang, która powoduje ich otwarcie w narzędziu VMware.
Linie Shebang dla plików, które nie działają jak skrypty, ale i tak działają jak skrypty
rmusuwa pliki. To nie jest język skryptowy. #!/bin/rmMożna jednak uruchomić plik, który zaczyna się i jest oznaczony jako wykonywalny, a po uruchomieniu rmwywoływany jest na nim, usuwając go.
Często jest to rozumiane jako „plik sam się usuwa”. Ale plik tak naprawdę wcale nie działa. Jest to bardziej podobne do sytuacji opisanej powyżej dla .vmxplików.
Ponieważ jednak #!wiersz ułatwia uruchomienie prostej komendy (w tym argumentów wiersza komend), możesz w ten sposób wykonać pewne skrypty. Jako prosty przykład „skryptu” bardziej zaawansowanego niż #!/bin/rm, rozważ:
#!/usr/bin/env tee -a
To pobiera interakcję użytkownika, odsyła go z powrotem do użytkownika wiersz po wierszu i dołącza na końcu pliku „skryptowego”.
Przydatny? Nie bardzo. Ciekawe koncepcyjnie? Całkowicie! Tak. (Nieco.)
Podobne koncepcyjnie koncepcje programowania / skryptowania (dla zabawy)
Metakolecenia w QBasic / QuickBASIC, które zasygnalizowały kompilatorowi (dla skompilowanego kodu) opcje generowania kodu, ale były częścią komentarzy i dlatego zostały zignorowane podczas faktycznej kompilacji / interpretacji.
@Rinzwind Thx! (Przy okazji ta odpowiedź nie pochodzi nigdzie indziej, jeśli się nad tym zastanawiasz).
Eliah Kagan
@Rinzwind Nie martw się, z 8 pozytywnymi opiniami po 1 godzinie prawdopodobnie
wzrośnie
1
Jeśli zawsze jest ignorowane, to co robi -xflaga Pythonów ?
gerrit
4
@gerrit Dobre pytanie. W każdym języku, w którym interpreter / kompilator zgłasza komunikaty z numerami wierszy, treść komentarzy jest ignorowana, ale wiersze komentarza są nadal liczone . Dodanie komentarza lub pustego wiersza przed wierszem kodu powoduje nadal zwiększenie tego wiersza kodu. -x„pomiń [s] pierwszą linię ...” druga linia jest numerowana 1zamiast 2, trzecia linia 2zamiast 3itd. Dlatego nie powinieneś używać tej flagi. ;) -xsłuży do tworzenia skryptów w systemach operacyjnych innych niż Unix, których składnia podobna do shebang nie zaczyna się od #(dlatego nie jest komentarzem w języku Python).
Eliah Kagan
4
W Perl, jeśli interpreter jest uruchamiany bezpośrednio ( perl script.plw porównaniu ./script.pl), a następnie interpreter będzie czytać wiersz shebang do analizowania takich jak flagi -w. Nie zaleca się jednak polegania na tej funkcji.
OrangeDog,
7
Shebang to sekwencja znaków składająca się ze znaku liczby znaków i wykrzyknika (np. „#!”), Gdy występuje jako początkowe dwa znaki w początkowej linii skryptu.
W systemach operacyjnych * nix, gdy uruchamiany jest skrypt rozpoczynający się od shebang, moduł ładujący program analizuje resztę początkowej linii skryptu jako dyrektywę interpretera; zamiast tego uruchamiany jest określony program interpretera, przekazując mu jako argument ścieżkę, która była początkowo używana podczas próby uruchomienia skryptu. Na przykład, jeśli skrypt ma nazwę ścieżki „path / to / your-script” i zaczyna się od następującego wiersza:
#!/bin/sh
następnie program ładujący program jest instruowany, aby zamiast tego uruchomić program „/ bin / sh”, np. powłokę Bourne'a lub kompatybilną powłokę, przekazując „path / to / your-script” jako pierwszy argument.
W związku z tym skrypt nosi nazwę ścieżki „path / to / python-script” i zaczyna się od następującego wiersza:
#!/bin/python
następnie załadowany program jest instruowany, aby zamiast tego uruchomić program „/ bin / python”, np. interpreter języka Python, przekazując „path / to / python-script” jako pierwszy argument.
W skrócie „#” skomentuje linię, a sekwencja znaków „#!” występowanie jako pierwszych dwóch znaków w początkowej linii skryptu ma znaczenie opisane powyżej.
Źródło: Niektóre sekcje tej odpowiedzi pochodzą (z niewielkimi modyfikacjami) z Shebang (Unix) na angielskiej Wikipedii (przez autorów Wikipedii ). Ten artykuł jest objęty licencją CC-BY-SA 3.0 , tak samo jak treść użytkownika tutaj w AU, więc to wyprowadzenie jest dozwolone z przypisaniem.
#!nazywa się, shebanggdy występuje jako początkowe dwa znaki w początkowej linii skryptu. Jest używany w skryptach do wskazania interpretera do wykonania. shebangJest z systemu operacyjnego (kernel), a nie do osłony; więc nie będzie interpretowane jako komentarz.
Ogólnie, jeśli plik jest wykonywalny, ale tak naprawdę nie jest programem wykonywalnym (binarnym), a taka linia jest obecna, program określony po #! zaczyna się od skryptu i wszystkich jego argumentów. Te dwa znaki # i! muszą być pierwszymi dwoma bajtami w pliku!
Jeśli porównanie jest prawdziwe, reszta linii jest analizowana przez jądro Linuksa, które wykonuje kolejne execwywołanie ze ścieżką /usr/bin/env pythoni bieżącym plikiem jako pierwszym argumentem:
/usr/bin/env python /path/to/script.py
i działa to na każdy język skryptowy, który używa #jako znaku komentarza.
I tak, możesz wykonać nieskończoną pętlę za pomocą:
printf '#!/a\n'| sudo tee /a
sudo chmod +x /a
/a
Bash rozpoznaje błąd:
-bash:/a: /a: bad interpreter:Too many levels of symbolic links
#! akurat jest czytelny dla ludzi, ale nie jest to wymagane.
Jeśli plik zaczął się od różnych bajtów, execwywołanie systemowe użyłoby innej procedury obsługi. Innym najważniejszym wbudowanym modułem obsługi są pliki wykonywalne ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305, który sprawdza bajty 7f 45 4c 46(które również są ludźmi) czytelne dla .ELF). Potwierdźmy to, czytając 4 pierwsze bajty /bin/ls, czyli plik wykonywalny ELF:
Nie sądzę jednak, że POSIX określa shebangs: https://unix.stackexchange.com/a/346214/32558 , chociaż wspomina o tym w sekcjach uzasadnienia oraz w formie „jeśli skrypty wykonywalne są obsługiwane przez system, coś może zdarzyć".
#include
. Tam też#
nie jest to komentarz.Odpowiedzi:
#!
Linia jest używana przed prowadzony jest skrypt, a następnie ignorowane , gdy skrypt jest uruchamiany.Pytasz, jaka jest różnica między linią shebang a zwykłym komentarzem.
Linia zaczynająca się od
#!
jest tak samo komentarzem jak każda inna linia zaczynająca się od#
. Dzieje się tak, jeśli#!
jest to pierwszy wiersz pliku lub gdziekolwiek indziej.#!/bin/sh
ma efekt , ale nie jest odczytywany przez samego tłumacza .#
nie jest komentarzem we wszystkich językach programowania, ale, jak wiecie, jest komentarzem w powłokach w stylu Bourne'a, w tymsh
ibash
(a także w większości takich powłokcsh
). To także komentarz w Pythonie . Jest to komentarz w wielu plikach konfiguracyjnych, które wcale nie są skryptami (jak/etc/fstab
).Załóżmy, że skrypt powłoki zaczyna się od
#!/bin/sh
. To jest komentarz, a tłumacz (powłoka) ignoruje wszystko w wierszu po#
znaku.Celem
#!
linii nie jest udzielanie informacji tłumaczowi. Celem tego#!
wiersza jest poinformowanie systemu operacyjnego (lub innego procesu uruchamiającego interpreter), co ma być używane jako interpreter .Jeśli skrypt zostanie wywołany jako plik wykonywalny, na przykład przez uruchomienie
./script.sh
, system przejdzie do pierwszego wiersza, aby sprawdzić, czy zaczyna się od#!
, po którym następuje zero lub więcej spacji, a następnie polecenie. Jeśli tak, uruchamia to polecenie z nazwą skryptu jako argumentu. W tym przykładzie działa/bin/sh script.sh
(lub technicznie/bin/sh ./script.sh
).Jeśli skrypt zostanie wywołany przez jawne wywołanie interpretera,
#!
linia nigdy nie zostanie sprawdzona. Więc jeśli uruchomiszsh script.sh
, pierwsza linia nie ma wpływu. Jeśliscript2.sh
pierwszym wierszem jest#!/usr/games/nibbles
, uruchomieniesh script2.sh
nie spróbuje otworzyć skryptu wnibbles
(ale./script2.sh
zrobi).Zauważysz, że w żadnym przypadku rozszerzenie skryptu (
.sh
), jeśli takie posiada, nie wpływa na sposób jego działania. W systemie uniksowym zwykle nie wpływa to na sposób uruchamiania skryptu. W niektórych innych systemach, takich jak Windows,#!
linia shebang może być całkowicie ignorowana przez system, a rozszerzenie może określać, co uruchamia skrypty. (Nie oznacza to, że musisz podawać rozszerzenia skryptów, ale jest to jeden z powodów, dla których tak robisz, powinny być poprawne).#!
został wybrany, aby służyć temu celowi właśnie dlatego , że#
zaczyna się komentarz.#!
Linia jest w systemie, a nie tłumacz, i powinno być ignorowane przez interpreter.Linia Shebang dla skryptów Bash
Ty (pierwotnie) powiedział użyć
#!/bin/sh
dlabash
skryptów. Powinieneś to zrobić tylko wtedy, gdy skrypt nie wymaga żadnego zbash
rozszerzeń -sh
musi być w stanie uruchomić skrypt.sh
nie zawsze jest dowiązaniem symbolicznym dobash
. Często, w tym na wszystkich ostatnio zdalnych systemach Debian i Ubuntu ,sh
jest dowiązaniem symbolicznymdash
.Linia Shebang dla skryptów Python
Powiedziałeś także (w pierwszej wersji swojego pytania, przed edycją), że uruchamiasz skrypty Pythona
#!/bin/sh read by the interpretor
. Jeśli masz na myśli dosłownie, zdecydowanie powinieneś przestać to robić. Jeślihello.py
zaczyna się od tej linii, uruchamianie./hello.py
wykonuje:/bin/sh
spróbuje wykonać skrypt o nazwieread
(zeby the interpretor hello.py
swoimi argumentami),read
(miejmy nadzieję) nie zostanie znaleziony, a twój skrypt w Pythonie nigdy nie będzie widoczny dla interpretera Pythona.Jeśli popełniasz ten błąd, ale nie mam problemu, który opisuję, prawdopodobnie
python hello.py
wywołujesz skrypty Pythona, jawnie określając interpreter (np. ), Co powoduje zignorowanie pierwszej linii. Kiedy dystrybuujesz swoje skrypty innym osobom lub używasz ich przez długi czas później, może nie być jasne, że jest to konieczne do ich działania. Najlepiej je teraz naprawić. Lub przynajmniej całkowicie usuń pierwszy wiersz, aby w przypadku niepowodzenia uruchomienia./
komunikat o błędzie miał sens.W przypadku skryptów w języku Python, jeśli wiesz, gdzie jest (lub będzie) interpreter języka Python, możesz napisać
#!
wiersz w ten sam sposób:Lub, jeśli jest to skrypt w języku Python 3, należy określić
python3
, ponieważpython
prawie zawsze jest to język Python 2 :Problem polega jednak na tym, że chociaż
/bin/sh
powinien istnieć zawsze i/bin/bash
prawie zawsze istnieje w systemachbash
z systemem operacyjnym, Python może istnieć w różnych miejscach.Dlatego wielu programistów Python używa tego zamiast tego:
(Lub
#!/usr/bin/env python3
dla Python 3.)To sprawia, że skrypt polega na
env
byciu w „właściwym miejscu” zamiast napython
byciu we właściwym miejscu. To dobrze, ponieważ:env
prawie zawsze znajduje się w/usr/bin
.python
powinien zostać uruchomiony, jest ten, który pojawia się jako pierwszy wPATH
. Począwszyhello.py
od#!/usr/bin/env python
make./hello.py
run/usr/bin/env python hello.py
, który jest (praktycznie) równoważny z bieganiempython hello.py
.Nie możesz użyć
#!python
tego, że:/
).python
w bieżącym katalogu . Przeszukiwanie ścieżki, gdy polecenie nie zawiera ukośnika, jest specyficznym zachowaniem powłoki.Czasami Python lub inny skrypt, który nie jest skryptem powłoki, będzie miał linię shebang zaczynającą się od miejsca, w
#!/bin/sh ...
którym...
znajduje się inny kod. Czasami jest to poprawne, ponieważ istnieją pewne sposoby wywołania powłoki (sh
) Bourne'a zgodnej z argumentami, aby wywołać interpreter Pythona. (Jeden z argumentów prawdopodobnie będzie zawierałpython
.) Jednak dla większości celów#!/usr/bin/env python
jest prostszy, bardziej elegancki i bardziej prawdopodobne, że będzie działał tak, jak chcesz.Linie Shebang w innych językach
Wiele języków programowania i skryptów oraz niektóre inne formaty plików służą
#
jako komentarz. Dla każdego z nich plik w języku może być uruchomiony przez program, który bierze go jako argument, określając program w pierwszym wierszu po#!
.W niektórych językach programowania
#
zwykle nie jest komentarzem, ale jako szczególny przypadek pierwszy wiersz jest ignorowany, jeśli zaczyna się od#!
. Ułatwia to użycie#!
składni, nawet jeśli w#
innym przypadku nie czyni komentarza wierszem.Linie Shebang dla plików, które nie działają jako skrypty
Chociaż jest to mniej intuicyjne, każdy plik, którego format pliku może pomieścić pierwszą linię rozpoczynającą się od
#!
następnej pełnej ścieżki pliku wykonywalnego, może mieć linię shebang. Jeśli to zrobisz, a plik zostanie oznaczony jako wykonywalny, możesz uruchomić go jak program ... powodując jego otwarcie jak dokument.Niektóre aplikacje używają tego zachowania celowo. Na przykład w VMware
.vmx
pliki definiują maszyny wirtualne. Możesz „uruchomić” maszynę wirtualną tak, jakby to był skrypt, ponieważ pliki te są oznaczone jako pliki wykonywalne i mają linię shebang, która powoduje ich otwarcie w narzędziu VMware.Linie Shebang dla plików, które nie działają jak skrypty, ale i tak działają jak skrypty
rm
usuwa pliki. To nie jest język skryptowy.#!/bin/rm
Można jednak uruchomić plik, który zaczyna się i jest oznaczony jako wykonywalny, a po uruchomieniurm
wywoływany jest na nim, usuwając go.Często jest to rozumiane jako „plik sam się usuwa”. Ale plik tak naprawdę wcale nie działa. Jest to bardziej podobne do sytuacji opisanej powyżej dla
.vmx
plików.Ponieważ jednak
#!
wiersz ułatwia uruchomienie prostej komendy (w tym argumentów wiersza komend), możesz w ten sposób wykonać pewne skrypty. Jako prosty przykład „skryptu” bardziej zaawansowanego niż#!/bin/rm
, rozważ:To pobiera interakcję użytkownika, odsyła go z powrotem do użytkownika wiersz po wierszu i dołącza na końcu pliku „skryptowego”.
Przydatny? Nie bardzo. Ciekawe koncepcyjnie? Całkowicie! Tak. (Nieco.)
Podobne koncepcyjnie koncepcje programowania / skryptowania (dla zabawy)
Skrypty / programy, które są w wielu językach jednocześnie , na przykład w celu symulacji funkcji haszowania w systemach operacyjnych, które jej nie miały .
(Programy te nazywane są poliglotami , ale nie należy tego mylić z innym poczuciem poliglota w rozwoju oprogramowania , programie / projekcie, w którym różne części są napisane w różnych językach.)
Metakolecenia w QBasic / QuickBASIC, które zasygnalizowały kompilatorowi (dla skompilowanego kodu) opcje generowania kodu, ale były częścią komentarzy i dlatego zostały zignorowane podczas faktycznej kompilacji / interpretacji.
źródło
-x
flaga Pythonów ?-x
„pomiń [s] pierwszą linię ...” druga linia jest numerowana1
zamiast2
, trzecia linia2
zamiast3
itd. Dlatego nie powinieneś używać tej flagi. ;)-x
służy do tworzenia skryptów w systemach operacyjnych innych niż Unix, których składnia podobna do shebang nie zaczyna się od#
(dlatego nie jest komentarzem w języku Python).perl script.pl
w porównaniu./script.pl
), a następnie interpreter będzie czytać wiersz shebang do analizowania takich jak flagi-w
. Nie zaleca się jednak polegania na tej funkcji.Shebang to sekwencja znaków składająca się ze znaku liczby znaków i wykrzyknika (np. „#!”), Gdy występuje jako początkowe dwa znaki w początkowej linii skryptu.
W systemach operacyjnych * nix, gdy uruchamiany jest skrypt rozpoczynający się od shebang, moduł ładujący program analizuje resztę początkowej linii skryptu jako dyrektywę interpretera; zamiast tego uruchamiany jest określony program interpretera, przekazując mu jako argument ścieżkę, która była początkowo używana podczas próby uruchomienia skryptu. Na przykład, jeśli skrypt ma nazwę ścieżki „path / to / your-script” i zaczyna się od następującego wiersza:
następnie program ładujący program jest instruowany, aby zamiast tego uruchomić program „/ bin / sh”, np. powłokę Bourne'a lub kompatybilną powłokę, przekazując „path / to / your-script” jako pierwszy argument.
W związku z tym skrypt nosi nazwę ścieżki „path / to / python-script” i zaczyna się od następującego wiersza:
następnie załadowany program jest instruowany, aby zamiast tego uruchomić program „/ bin / python”, np. interpreter języka Python, przekazując „path / to / python-script” jako pierwszy argument.
W skrócie „#” skomentuje linię, a sekwencja znaków „#!” występowanie jako pierwszych dwóch znaków w początkowej linii skryptu ma znaczenie opisane powyżej.
Aby uzyskać szczegółowe informacje, zobacz Dlaczego niektóre skrypty zaczynają się od #! ...
Źródło: Niektóre sekcje tej odpowiedzi pochodzą (z niewielkimi modyfikacjami) z Shebang (Unix) na angielskiej Wikipedii (przez autorów Wikipedii ). Ten artykuł jest objęty licencją CC-BY-SA 3.0 , tak samo jak treść użytkownika tutaj w AU, więc to wyprowadzenie jest dozwolone z przypisaniem.
źródło
#!
nazywa się,shebang
gdy występuje jako początkowe dwa znaki w początkowej linii skryptu. Jest używany w skryptach do wskazania interpretera do wykonania.shebang
Jest z systemu operacyjnego (kernel), a nie do osłony; więc nie będzie interpretowane jako komentarz.Dzięki uprzejmości: http://en.wikipedia.org/wiki/Shebang_%28Unix%29
Szczegółowe informacje: http://wiki.bash-hackers.org/scripting/basics#the_shebang
źródło
Nie, jest używany tylko przez
exec
wywołanie systemowe jądra Linuksa i traktowany jako komentarz przez tłumaczaKiedy robisz na bash:
w Linuksie wywołuje to wywołanie
exec
systemowe ze ścieżką./something
.Ta linia jądra zostaje wywołana w pliku przekazanym do
exec
: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25Odczytuje pierwsze bajty pliku i porównuje je
#!
.Jeśli porównanie jest prawdziwe, reszta linii jest analizowana przez jądro Linuksa, które wykonuje kolejne
exec
wywołanie ze ścieżką/usr/bin/env python
i bieżącym plikiem jako pierwszym argumentem:i działa to na każdy język skryptowy, który używa
#
jako znaku komentarza.I tak, możesz wykonać nieskończoną pętlę za pomocą:
Bash rozpoznaje błąd:
#!
akurat jest czytelny dla ludzi, ale nie jest to wymagane.Jeśli plik zaczął się od różnych bajtów,
exec
wywołanie systemowe użyłoby innej procedury obsługi. Innym najważniejszym wbudowanym modułem obsługi są pliki wykonywalne ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305, który sprawdza bajty7f 45 4c 46
(które również są ludźmi) czytelne dla.ELF
). Potwierdźmy to, czytając 4 pierwsze bajty/bin/ls
, czyli plik wykonywalny ELF:wynik:
Więc kiedy jądro zobaczy te bajty, pobiera plik ELF, poprawnie zapisuje go w pamięci i rozpoczyna z nim nowy proces. Zobacz także: https://stackoverflow.com/questions/8352535/how-does-kernel-get-an-executable-binary-file-running-under-linux/31394861#31394861
Na koniec możesz dodać własne
binfmt_misc
mechanizmy shebang z mechanizmem. Na przykład możesz dodać niestandardowy moduł obsługi.jar
plików . Ten mechanizm obsługuje nawet programy obsługi według rozszerzeń plików. Inną aplikacją jest przezroczyste uruchamianie plików wykonywalnych o innej architekturze za pomocą QEMU .Nie sądzę jednak, że POSIX określa shebangs: https://unix.stackexchange.com/a/346214/32558 , chociaż wspomina o tym w sekcjach uzasadnienia oraz w formie „jeśli skrypty wykonywalne są obsługiwane przez system, coś może zdarzyć".
źródło