Jeśli script.sh jest czymś typowym, takim jak
#!/bin/bash echo "Hello World!"
Czy jest preferowana sposób na uruchomienie skryptu? Myślę, że najpierw musisz go chmodować, aby stał się wykonywalny?
Odpowiedź
Dla twojego konkretnego skryptu każdy sposób zadziała, z wyjątkiem że ./script.sh
wymaga wykonania i czytelnych bitów, podczas gdy bash script.sh
wymaga tylko czytelnego bitu.
Powód różnica w wymaganiach dotyczących uprawnień polega na tym, jak ładowany jest program, który interpretuje twój skrypt:
-
./script.sh
sprawia, że twoja powłoka uruchamia plik tak, jakby był zwykłym wykonywalny.
Powłoka forkuje się i używa wywołania systemowego (np. execve
), aby zmusić system operacyjny do wykonania pliku w procesie rozwidlonym. System operacyjny sprawdzi uprawnienia do pliku (dlatego bit wykonania musi zostać ustawiony) i przekaże żądanie do programu ładującego , który sprawdza plik i określa, jak go wykonać. W Linuksie skompilowane pliki wykonywalne zaczynają się od magicznej liczby ELF , a skrypty zaczynają się od #!
( hashbang ). Nagłówek hashbang oznacza, że plik jest skryptem i musi być zinterpretowany przez program określony po hashbangu. Umożliwia to skryptowi aby poinformować system, jak interpretować skrypt.
Wraz z Twoim skryptem program ładujący wykona /bin/bash
i przekaże ./script.sh
jako argument wiersza poleceń.
-
bash script.sh
sprawia, że powłoka działabash
i przechodziscript.sh
jako argument wiersza poleceń
W ten sposób system operacyjny załaduje (nawet nie patrząc na script.sh
, ponieważ jest to tylko argument wiersza poleceń). Utworzony proces bash
zinterpretuje następnie script.sh
, ponieważ został on przekazany jako argument wiersza polecenia. Ponieważ script.sh
jest odczytywane tylko przez bash
jako zwykły plik, bit wykonania nie jest wymagany.
Polecam używanie ./script.sh
, ponieważ możesz nie wiedzieć, którego interpretera wymaga skrypt. Pozwól więc programowi ładującemu określić to za Ciebie.
Komentarze
- Jeśli bit wykonywalny nie jest ustawiony, możesz również uruchomić skrypt, wykonując ". ./script.sh"
- @Dog Masz rację. Kropka to skrót do wbudowanego polecenia ' source ' , który uruchamia skrypt w bieżącym procesie bash. Dlatego wymagany jest tylko czytelny bit.
- @Dogeatcatworld to prawda, ale uruchomienie
. ./script.sh
to nie to samo rzecz jako (lub./script.sh
. Rozważ skrypt#!/usr/bin/python -V
< newline >print test
. - Uważaj, że pozyskiwanie skryptu może spowodować zanieczyszczenie sesji interaktywnej. Na przykład, jeśli skrypt zmieni zmienną środowiskową PATH, ta zmiana wpłynie na polecenia uruchamiane po źródle. To podejście powinno być naprawdę zarezerwowane dla sytuacji, w których polegasz na efektach ubocznych (skrypty konfiguracji środowiska i tym podobne). W innych sytuacjach, w których możesz ' t zmienić uprawnienia, najbezpieczniejszym podejściem jest uruchomienie polecenia w wierszu shebang, po którym następuje nazwa skryptu.
- Zwróć uwagę, że , jeśli pozyskujesz skrypt w bieżącym katalogu, nie musisz używać ./ ; po prostu powiedz
. script.sh
. Ale zgadzam się z ludźmi, którzy odradzają używanie polecenia.
w skryptach, które nie miały być wywoływane w ten sposób. Dziwię się, że nikt o tym nie wspomniał, jeśli skrypt zawiera poleceniaexit
, a Ty go pobierasz, może Cię wylogować. Mniej poważnym problemem byłoby wykonanie przez skryptcd
, ponieważ wpłynęłoby to również na powłokę nadrzędną (interaktywną).
Odpowiedz
bash script.sh
wywołuje skrypt bezpośrednio przy użyciu basha.
./script.sh
używa shebang #!/bin/bash
do określenia sposobu wykonania.
Jeśli naprawdę chcesz wiedzieć, który plik binarny jest wykonywany, jeśli wykonasz bash script.sh
możesz się tego dowiedzieć z which bash
.
W twoim przykładzie nie ma to znaczenia. Tak, musisz chmod +x script.sh
, aby móc go wykonać bezpośrednio przez ./script.sh
.
Komentarze
Odpowiedź
Utwórz plik Delete_Self.sh w ten sposób:
#!/bin/rm echo I am still here!
Uruchom to skrypt jako sh Delete_Self.sh
, zobaczysz komunikat „Nadal tu jestem!” echo z powrotem.
Ustaw go jako wykonywalny i uruchom jako ./Delete_Self.sh
zobaczysz, że nic nie jest powtórzone, a plik Delete_Self.sh
zniknął.
Różnica jest taka, że:
-
bash script.sh
zignoruje #! linia, ponieważ bash jest określony jako program do uruchamiania script.sh. -
./script.sh
odczyta #! wiersz określający program do uruchomieniascript.sh
.
Komentarze
- +1 dla ładny przykład
Odpowiedź
Oprócz innych odpowiedzi, znajomość różnicy między uruchomieniem skryptu przez ./script.sh
(i) i źródło ./script.sh
(ii) są przydatne – wersja (i) tworzy nową powłokę, w której można uruchomić polecenie, podczas gdy (ii) uruchamia go w bieżącej powłoce – co może być obowiązkowe, jeśli plik wykonywalny zmienia zmienne środowiskowe, które muszą zostać zachowane po zakończeniu działania pliku wykonywalnego. Na przykład, aby aktywować środowisko Python Conda, należy użyć następujących elementów:
source activate my_env
Uwaga. Inną alternatywą dla source
, którą możesz napotkać, jest wbudowane .
, tj.
. activate my_env
/bin/bash
jest pierwszymbash
w swoim$PATH
.#!/bin/bash
działa tylko wtedy, gdy jest/bin/bash
./script.sh
.