Dlaczego wszystkie pliki skryptów zaczynają się od
#!/bin/sh
lub z
#!/bin/csh
Czy to jest wymagane? Jaki jest tego cel? Jaka jest różnica między nimi?
Dlaczego wszystkie pliki skryptów zaczynają się od
#!/bin/sh
lub z
#!/bin/csh
Czy to jest wymagane? Jaki jest tego cel? Jaka jest różnica między nimi?
Odpowiedzi:
Jest to znane jako Shebang:
http://en.wikipedia.org/wiki/Shebang_(Unix)
#! interpreter [opcjonalny-arg]
Shebang ma znaczenie tylko wtedy, gdy skrypt ma pozwolenie na wykonanie (np. Chmod u + x script.sh).
Kiedy powłoka wykonuje skrypt, użyje określonego interpretera.
Przykład:
#!/bin/bash
# file: foo.sh
echo 1
$ chmod u+x foo.sh
$ ./foo.sh
1
#!Linia informuje jądro (w szczególności realizacji execvewywołania systemowego), że ten program jest napisany w języku interpretowanym; bezwzględna nazwa ścieżki, która następuje, identyfikuje interpretera. Programy skompilowane do kodu maszynowego zaczynają się od innej sekwencji bajtów - w większości nowoczesnych Uniksów, 7f 45 4c 46( ^?ELF), która je identyfikuje.
Możesz umieścić bezwzględną ścieżkę do dowolnego programu po tagu #!, o ile sam ten program nie jest #!skryptem. Jądro przepisuje wywołanie
./script arg1 arg2 arg3 ...
gdzie ./scriptzaczyna się, powiedzmy, #! /usr/bin/perltak, jakby wiersz poleceń faktycznie istniał
/usr/bin/perl ./script arg1 arg2 arg3
Lub, jak widziałeś, możesz użyć #! /bin/shdo napisania skryptu, który ma być interpretowany przez sh.
#!Linii są przetwarzane tylko wtedy, gdy bezpośrednio wywołać skrypt ( ./scriptw linii poleceń); plik musi być również wykonywalny ( chmod +x script). Jeśli nie linia nie jest konieczne (i będą ignorowane, jeśli jest obecny), a plik nie musi być wykonywalny. Punkt z tej funkcji jest umożliwienie Ci bezpośrednio invoke programów interpretowany języków bez konieczności znać język, jakim są napisane. (Do - będzie można odkryć, że bardzo wiele programów akcji są w rzeczywistości przy użyciu tej funkcji.)sh ./script#!grep '^#!' /usr/bin/*
Oto kilka zasad korzystania z tej funkcji:
#!Muszą być dwie bardzo pierwsze bajty w pliku. W szczególności plik musi być kodowany zgodnie z ASCII (np. UTF-8 będzie działać, ale UTF-16 nie) i nie może zaczynać się od „znaku kolejności bajtów”, w przeciwnym razie jądro nie rozpozna go jako #!scenariusz.#!musi być ścieżką bezwzględną (zaczyna się od /). Nie może zawierać znaków spacji, tabulacji ani nowej linii.#!i /. Nie umieszczaj tam więcej niż jednej spacji.#!linii, nie zostaną one rozwinięte.#! /usr/bin/awk -f), czasami jest to po prostu przydatne ( #! /usr/bin/perl -Tw). Niestety nie możesz umieścić dwóch lub więcej argumentów po ścieżce bezwzględnej.#! /usr/bin/env interpreterzamiast #! /absolute/path/to/interpreter. To prawie zawsze błąd. Sprawia, że zachowanie programu zależy od $PATHzmiennej użytkownika, który wywołuje skrypt. I nie wszystkie systemy są envna pierwszym miejscu.setuidlub setgidprzywilejów, nie mogą ich używać #!; muszą być skompilowane do kodu maszynowego. (Jeśli nie wiesz, co to setuidjest, nie martw się tym).Odnośnie csh, odnosi się to shmniej więcej do tego, co Nutrimat Advanced Tea Substitute ma do herbaty. Ma (a raczej miał; współczesne implementacje shdogoniły) szereg zalet w porównaniu shz interaktywnym użyciem, ale używanie go (lub jego następcy tcsh) do tworzenia skryptów jest prawie zawsze błędem . Jeśli nie znasz ogólnie skryptów powłoki, zdecydowanie zalecam zignorowanie tego i skupienie się na sh. Jeśli używasz cshkrewnego jako powłoki logowania, przełącz na bashlub zsh, aby interaktywny język poleceń był taki sam, jak język skryptowy, którego się uczysz.
#!; bez komentarza, czy to dobry styl. Zobacz to pytanie i moją odpowiedź, aby omówić zalety i wady #!/usr/bin/envwłamania.
#!/usr/bin/envbyła Właściwa Rzecz, ale pozostaje moim zdaniem, że prawie zawsze jest to zły pomysł.
Określa, jakiej powłoki (interpretera poleceń) używasz do interpretowania / uruchamiania skryptu. Każda powłoka różni się nieco sposobem interakcji z użytkownikiem i wykonywania skryptów (programów).
Kiedy wpisujesz polecenie w linii poleceń systemu Unix, wchodzisz w interakcję z powłoką.
Np. #!/bin/cshOdnosi się do powłoki C, powłoki /bin/tcsht, powłoki /bin/bashbash itp.
Możesz powiedzieć, której powłoki interaktywnej używasz
echo $SHELL
polecenie lub alternatywnie
env | grep -i shell
Możesz zmienić powłokę poleceń za pomocą chshpolecenia.
Każdy ma nieco inny zestaw poleceń i sposób przypisywania zmiennych oraz własny zestaw konstrukcji programistycznych. Na przykład instrukcja if-else z bash wygląda inaczej niż ta w powłoce C.
Ta strona może być interesująca, ponieważ "tłumaczy" pomiędzy poleceniami / składnią bash i tcsh.
Użycie dyrektywy w skrypcie powłoki umożliwia uruchamianie programów przy użyciu innej powłoki. Na przykład używam tcshpowłoki interaktywnie, ale często uruchamiam skrypty bash za pomocą / bin / bash w pliku skryptu.
Na bok:
Ta koncepcja rozciąga się również na inne skrypty. Na przykład, jeśli programujesz w Pythonie, umieścisz
#!/usr/bin/python
u góry programu w Pythonie
#! $SHELL? Czy to umieściłoby właściwą muszlę w Shebangu?
!#/bin/bash. Dyrektywy. Informuje system, jakiej powłoki należy użyć do wykonania skryptu powłoki.
$SHELLniekoniecznie mówi ci, z której powłoki aktualnie korzystasz; zwykle mówi ci o twojej domyślnej powłoce. zestawy tcsh $versioni $tcsh; zestawy bash $BASH_VERSION. Nie wszystkie muszle muszą mieć podobne mechanizmy.
#!Linia musi pasować do składni skryptu, a nie do powłoki interaktywnej używanej przez każdego, kto uruchamia skrypt.
#!/bin/csh -f;-fmówi powłoce nie pozyskać użytkownika.logini.cshrc, co sprawia, że szybciej uruchomić skrypt i unika zależności od ustawień użytkownika. (Lub jeszcze lepiej, nie pisz skryptów csh.) Nie używaj-fdo skryptów sh lub bash; nie ma tego samego znaczenia.