Istnieje kilka sposobów wykonania skryptu, z których znam:
/path/to/script # using the path (absolute or relative)
. script # using the . (dot)
source script # using the `source` command
Czy to więcej? Jakie są między nimi różnice? Czy są sytuacje, w których muszę korzystać z jednej, a nie drugiej?
shell-script
executable
phunehehe
źródło
źródło
Odpowiedzi:
Innym sposobem jest wywołanie interpretera i przekazanie mu ścieżki do skryptu:
Kropka i źródło są równoważne. (EDYCJA: nie, nie są: jak KeithB wskazuje w komentarzu do innej odpowiedzi: „.” Działa tylko w powłokach związanych z bash, gdzie „źródło” działa zarówno w powłokach związanych z bash, jak i csh.) Wykonuje skrypt w -place (tak jakbyś skopiował i wkleił skrypt tutaj). Oznacza to, że pozostaną wszystkie funkcje i zmienne nielokalne w skrypcie. Oznacza to również, że jeśli skrypt włoży płytę CD do katalogu, to po zakończeniu będziesz tam nadal.
Inne sposoby uruchamiania skryptu powodują uruchomienie go we własnej podpowłoce. Zmienne w skrypcie nie są jeszcze aktywne, gdy jest gotowe. Jeśli skrypt zmieni katalogi, nie wpłynie to na środowisko wywołujące.
Skrypty / path / to / script i / bin / sh różnią się nieco. Zazwyczaj skrypt ma „shebang” na początku, który wygląda następująco:
To jest ścieżka do interpretera skryptów. Jeśli określa innego interpretera niż ty, kiedy go wykonujesz, może on zachowywać się inaczej (lub w ogóle nie działać).
Na przykład skrypty Perla i Ruby zaczynają się (odpowiednio):
i
Jeśli wykonasz jeden z tych skryptów przez uruchomienie
/bin/sh script
, to w ogóle nie będą działać.Ubuntu w rzeczywistości nie używa powłoki bash, ale bardzo podobną o nazwie dash. Skrypty wymagające bash mogą działać nieco niepoprawnie po wywołaniu,
/bin/sh script
ponieważ właśnie wywołałeś skrypt bash za pomocą interpretera myślników.Inną niewielką różnicą między bezpośrednim wywołaniem skryptu a przekazaniem ścieżki skryptu do interpretera jest to, że skrypt musi być oznaczony jako wykonywalny, aby uruchomić go bezpośrednio, ale nie należy go uruchamiać, przekazując ścieżkę do interpretera.
Kolejna drobna odmiana: możesz poprzedzić dowolny z tych sposobów wykonania skryptu eval, więc możesz to zrobić
i tak dalej. W rzeczywistości nic to nie zmienia, ale pomyślałem, że dodam to dla dokładności.
źródło
sh
odpowiadadash
, ale niebash
.Większość osób debuguje skrypty powłoki, dodając do skryptu następujące flagi debugowania :
Ale to oznacza, że musisz otworzyć plik za pomocą edytora (zakładając, że masz uprawnienia do edycji pliku), dodając wiersz
set -x
, zapisz plik, a następnie uruchom plik. Następnie, gdy skończysz, musisz wykonać te same kroki i usunąćset -x
itp. Itp. Może to być uciążliwe.Zamiast robić to wszystko, możesz ustawić flagi debugowania w wierszu poleceń:
źródło
emulate sh 2>/dev/null
na szczycie moich skryptów powłoki. Po uruchomieniu z zsh powoduje to przejście do trybu zgodnego z POSIX. Podczas uruchamiania z innymi powłokami linia nie ma wpływu. Potem mogę uruchomić skryptzsh -x /path/to/script
. Podoba mi się tutaj zsh, ponieważ zapewnia lepsze ślady niż bash lub ksh.Shawn J. Goff przedstawił wiele dobrych punktów, ale nie uwzględnił całej historii:
Wiele skryptów systemowych (jak w init.d, w / etc itd.) Ma shebang
#!/bin/sh
, ale/bin/sh
w rzeczywistości jest symbolicznym łącznikiem z inną powłoką - w dawnych czasach/bin/bash
, obecnie/bin/dash
. Ale gdy jeden z nich zostanie wywołany jako/bin/sh
, zachowują się inaczej, tzn. Trzymają się trybu zgodności z POSIX.Jak oni to robią? Cóż, sprawdzają, jak zostały przywołane.
Czy sam skrypt Shells może przetestować sposób jego wywołania i wykonywać różne czynności, zależnie od tego? Tak, może. Sposób, w jaki ją wywołujesz, zawsze może prowadzić do różnych rezultatów, ale oczywiście rzadko robi się to, aby cię drażnić. :)
Ogólna zasada: jeśli uczysz się konkretnej powłoki, takiej jak bash, i piszesz polecenia z samouczka bash, nie umieszczaj
#!/bin/bash
nagłówka#!/bin/sh
, chyba że zaznaczono inaczej. W przeciwnym razie twoje polecenia mogą zawieść. A jeśli sam nie napisałeś skryptu, wywołaj go bezpośrednio (./foo.sh
,bar/foo.sh
) zamiast zgadywania powłoki (sh foo.sh
,sh bar/foo.sh
). Shebang powinien wywoływać odpowiednią skorupę.A oto dwa inne rodzaje wywołań:
źródło
.
isource
są równoważne, ponieważ nie spawnują podprocesu, ale wykonują polecenia w bieżącej powłoce. Jest to ważne, gdy skrypt ustawia zmienne środowiskowe lub zmienia bieżący katalog roboczy.Użycie ścieżki lub nadanie jej do
/bin/sh
utworzenia nowego procesu, w którym wykonywane są polecenia.źródło
Zastanawiam się, czy jest więcej ...
.
isource
są takie same. Po wykonaniu zmiany środowiskascript
zostaną zachowane. Zwykle byłby używany do pozyskiwania biblioteki Bash, więc biblioteka może być ponownie używana w wielu różnych skryptach.Jest to również dobry sposób na utrzymanie bieżącego katalogu. Jeśli zmienisz katalog w skrypcie, nie zostanie on zastosowany w powłoce, którą wykonujesz. Ale jeśli go uruchomisz, po zakończeniu skryptu zostanie zachowany bieżący katalog.
źródło
.
działa tylko w sh / bash i pokrewnych powłokach.source
działa również w csh i pokrewnych powłokach.Czy „ userland exec ” liczy się inaczej? Userland exec ładuje kod i uruchamia go bez użycia wywołania systemowego execve ().
źródło
Uruchamia skrypt w bieżącej powłoce, gdy katalog nie znajduje się na ścieżce.
źródło
. i źródło różnią się przynajmniej trochę w Zsh (tego używam), ponieważ
Działa, póki
nie potrzebuje
źródło