Pozyskanie skryptu spowoduje uruchomienie poleceń w bieżącym procesie powłoki.
Wykonanie skryptu spowoduje uruchomienie poleceń w nowym procesie powłoki.
Użyj źródła, jeśli chcesz, aby skrypt zmienił środowisko w aktualnie uruchomionej powłoce. użyj wykonać inaczej.
Jeśli nadal jesteś zdezorientowany, czytaj dalej.
Terminologia
Aby wyjaśnić niektóre typowe nieporozumienia dotyczące składni do wykonania i składni do źródła:
./myscript
Będzie to executemyscript pod warunkiem, że plik jest wykonywalny i znajduje się w bieżącym katalogu. Wiodąca kropka i ukośnik ( ./) oznaczają bieżący katalog. Jest to konieczne, ponieważ bieżącego katalogu zwykle nie ma (i zwykle nie powinno być) $PATH.
myscript
Będzie to wykonaćmyscript , jeśli plik jest wykonywalny i znajduje się w jakimś katalogu w $PATH.
source myscript
To będzie źródłomyscript . Plik nie musi być wykonywalny, ale musi być prawidłowym skryptem powłoki. Plik może znajdować się w bieżącym katalogu lub w katalogu w $PATH.
. myscript
To również źródłomyscript . Ta „pisownia” jest oficjalna zgodnie z definicją POSIX . Bash zdefiniowany sourcejako alias do kropki.
Demonstracja
Rozważ myscript.shnastępujące treści:
#!/bin/sh# demonstrate setting a variable
echo "foo: "$(env | grep FOO)
export FOO=foo
echo "foo: "$(env | grep FOO)# demonstrate changing of working directory
echo "PWD: "$PWD
cd somedir
echo "PWD: "$PWD
Przed wykonaniem skryptu najpierw sprawdzamy bieżące środowisko:
$ env | grep FOO
$ echo $PWD
/home/lesmana
Zmienna FOOnie jest zdefiniowana i jesteśmy w katalogu domowym.
Zmienna FOOnie jest ustawiona, a katalog roboczy nie zmienił się.
Dane wyjściowe skryptu wyraźnie pokazują, że zmienna została ustawiona, a katalog został zmieniony. Następnie kontrola pokazuje, że zmienna nie jest ustawiona, a katalog się nie zmienia. Co się stało? Zmiany zostały wprowadzone w nowej powłoce. Prąd powłoki zrodził nową powłokę, aby uruchomić skrypt. Skrypt działa w nowej powłoce, a wszystkie zmiany w środowisku obowiązują w nowej powłoce. Po zakończeniu skryptu nowa powłoka jest niszczona. Wszystkie zmiany środowiska w nowej powłoce są niszczone przez nową powłokę. Tylko tekst wyjściowy jest drukowany w bieżącej powłoce.
Zmienna FOO została ustawiona, a katalog roboczy zmienił się.
Pozyskanie skryptu nie tworzy nowej powłoki. Wszystkie polecenia są uruchamiane w bieżącej powłoce, a zmiany w środowisku obowiązują w bieżącej powłoce.
Zauważ, że w tym prostym przykładzie wynik wykonania jest taki sam, jak pozyskiwanie skryptu. Nie zawsze tak jest.
Kolejna demonstracja
Rozważ następujący skrypt pid.sh:
#!/bin/sh
echo $$
(specjalna zmienna $$rozwija się do PID aktualnie działającego procesu powłoki)
Najpierw wydrukuj PID bieżącej powłoki:
$ echo $$
25009
Źródło skryptu:
$ source pid.sh
25009
Uruchom skrypt, zwróć uwagę na PID:
$ ./pid.sh
25011
Źródło ponownie:
$ source pid.sh
25009
Wykonaj ponownie:
$ ./pid.sh
25013
Widać, że pozyskiwanie skryptu odbywa się w tym samym procesie, a wykonanie skryptu powoduje utworzenie nowego procesu za każdym razem. Ten nowy proces to nowa powłoka, która została stworzona do wykonania skryptu. Pozyskanie skryptu nie tworzy nowej powłoki, a zatem PID pozostaje taki sam.
streszczenie
Zarówno wyszukiwanie, jak i wykonywanie skryptu spowoduje uruchamianie poleceń w skrypcie wiersz po wierszu, tak jakbyś wpisywał te polecenia ręcznie wiersz po wierszu.
Różnice są następujące:
Po uruchomieniu skryptu otwierasz nową powłokę, wpisz polecenia w nowej powłoce, skopiuj dane wyjściowe z powrotem do bieżącej powłoki, a następnie zamknij nową powłokę. Wszelkie zmiany w środowisku będą obowiązywać tylko w nowej powłoce i zostaną utracone po zamknięciu nowej powłoki.
Podczas generowania skryptu wpisujesz polecenia w bieżącej powłoce. Wszelkie zmiany środowiska zostaną zastosowane i pozostaną w bieżącej powłoce.
Użyj źródła, jeśli chcesz, aby skrypt zmienił środowisko w aktualnie uruchomionej powłoce. użyj wykonać inaczej.
Jednym z zastosowań pozyskiwania jest stworzenie podstawowej formy pliku konfiguracyjnego dla twoich skryptów. Zaczynasz od ustawienia różnych zmiennych na wartości domyślne, a następnie na źródło w coś takiego jak myscript.conf - a ten skrypt źródłowy może mieć instrukcje przypisania, które zastępują dowolne wartości. Ponieważ pobrany skrypt nie zaczyna się od # / bin / bash, nie jest zalecane, aby wykonać go bezpośrednio.
LawrenceC
Więc source jest jak uruchamianie go w zasięgu globalnym, a wykonanie powoduje utworzenie nowego zasięgu lokalnego. Czy można to rozszerzyć na funkcję w skrypcie? wykonać funkcję (normalnie) czy „ją„ zinterpretować ”?
aliteralmind,
2
Czy istnieje różnica między używaniem source myscript.sha . myscript.sh?
Holloway,
2
praktycznie nie ma różnicy, jeśli używasz bash. source to alias do kropki w bash.
lesmana
1
Uwielbiam to, gdy ludzie podają tak wyszukane przykłady, aby nawet początkujący użytkownicy Linuksa tacy jak ja mogli zrozumieć. Dzięki!
Julius
21
Wykonanie skryptu powoduje uruchomienie go w osobnym procesie potomnym, tzn. W celu przetworzenia skryptu wywoływana jest osobna instancja powłoki. Oznacza to, że żadnych zmiennych środowiskowych itp. Zdefiniowanych w skrypcie nie można aktualizować w powłoce nadrzędnej (bieżącej).
Pozyskanie skryptu oznacza, że jest on analizowany i wykonywany przez samą bieżącą powłokę. To tak, jakbyś wpisał treść skryptu. Z tego powodu skrypt nie musi być wykonywalny. Ale oczywiście musi być wykonywalny.
Jeśli masz argumenty pozycyjne w bieżącej powłoce, są one niezmienione.
chociaż ta odpowiedź jest poprawna pod każdym względem, bardzo trudno ją zrozumieć, ponieważ została wykazana przy użyciu innej koncepcji (ustawiania parametrów pozycyjnych), co moim zdaniem jest jeszcze bardziej mylące niż różnica w pozyskiwaniu i wykonywaniu samej siebie.
lesmana
9
pozyskiwanie jest zasadniczo takie samo, jak wpisywanie każdej linii skryptu w wierszu polecenia pojedynczo ...
Wykonanie rozpoczyna nowy proces, a następnie uruchamia każdą linię skryptu, modyfikując tylko bieżące środowisko o to, co zwraca.
Oprócz powyższego wykonanie skryptu ./myscriptwymaga uprawnień do wykonywania skryptu myscript, podczas gdy pozyskiwanie nie wymaga uprawnień do wykonywania. Dlatego wcześniej chmod +x myscriptnie jest to wymaganesource myscript
To prawda, ale jeśli to jest problem, zawsze możesz uruchomić bash myscript.
Daniel Beck
5
Pozyskiwanie zawiera wszystkie dodatkowe zmienne zdefiniowane w skrypcie.
Więc jeśli masz konfiguracje lub definicje funkcji, powinieneś je pobrać, a nie wykonać. Wykonania są niezależne od środowiska rodziców.
Jeśli dobrze pamiętam, wykonanie skryptu uruchamia plik wykonywalny w #!wierszu z plikiem skryptu jako argumentem (zazwyczaj uruchamianie nowej powłoki i efektywne pozyskiwanie skryptu do nowej powłoki, jak w przypadku #!/bin/sh);
podczas gdy pozyskiwanie skryptu powoduje wykonanie każdego wiersza w bieżącym środowisku powłoki, co jest przydatne do mutowania bieżącej powłoki (na przykład umożliwiając zdefiniowanie funkcji powłoki i eksport zmiennych środowiskowych).
sourcepolecenie wykonuje podany skrypt (uprawnienie do wykonywania nie jest obowiązkowe ) w bieżącym środowisku powłoki, natomiast ./wykonuje podany skrypt wykonywalny w nowej powłoce.
Odpowiedzi:
Krótka odpowiedź
Pozyskanie skryptu spowoduje uruchomienie poleceń w bieżącym procesie powłoki.
Wykonanie skryptu spowoduje uruchomienie poleceń w nowym procesie powłoki.
Użyj źródła, jeśli chcesz, aby skrypt zmienił środowisko w aktualnie uruchomionej powłoce. użyj wykonać inaczej.
Jeśli nadal jesteś zdezorientowany, czytaj dalej.
Terminologia
Aby wyjaśnić niektóre typowe nieporozumienia dotyczące składni do wykonania i składni do źródła:
Będzie to execute
myscript
pod warunkiem, że plik jest wykonywalny i znajduje się w bieżącym katalogu. Wiodąca kropka i ukośnik (./
) oznaczają bieżący katalog. Jest to konieczne, ponieważ bieżącego katalogu zwykle nie ma (i zwykle nie powinno być)$PATH
.Będzie to wykonać
myscript
, jeśli plik jest wykonywalny i znajduje się w jakimś katalogu w$PATH
.To będzie źródło
myscript
. Plik nie musi być wykonywalny, ale musi być prawidłowym skryptem powłoki. Plik może znajdować się w bieżącym katalogu lub w katalogu w$PATH
.To również źródło
myscript
. Ta „pisownia” jest oficjalna zgodnie z definicją POSIX . Bash zdefiniowanysource
jako alias do kropki.Demonstracja
Rozważ
myscript.sh
następujące treści:Przed wykonaniem skryptu najpierw sprawdzamy bieżące środowisko:
Zmienna
FOO
nie jest zdefiniowana i jesteśmy w katalogu domowym.Teraz wykonujemy plik:
Sprawdź ponownie środowisko:
Zmienna
FOO
nie jest ustawiona, a katalog roboczy nie zmienił się.Dane wyjściowe skryptu wyraźnie pokazują, że zmienna została ustawiona, a katalog został zmieniony. Następnie kontrola pokazuje, że zmienna nie jest ustawiona, a katalog się nie zmienia. Co się stało? Zmiany zostały wprowadzone w nowej powłoce. Prąd powłoki zrodził nową powłokę, aby uruchomić skrypt. Skrypt działa w nowej powłoce, a wszystkie zmiany w środowisku obowiązują w nowej powłoce. Po zakończeniu skryptu nowa powłoka jest niszczona. Wszystkie zmiany środowiska w nowej powłoce są niszczone przez nową powłokę. Tylko tekst wyjściowy jest drukowany w bieżącej powłoce.
Teraz źródło pliku:
Sprawdź ponownie środowisko:
Zmienna FOO została ustawiona, a katalog roboczy zmienił się.
Pozyskanie skryptu nie tworzy nowej powłoki. Wszystkie polecenia są uruchamiane w bieżącej powłoce, a zmiany w środowisku obowiązują w bieżącej powłoce.
Zauważ, że w tym prostym przykładzie wynik wykonania jest taki sam, jak pozyskiwanie skryptu. Nie zawsze tak jest.
Kolejna demonstracja
Rozważ następujący skrypt
pid.sh
:(specjalna zmienna
$$
rozwija się do PID aktualnie działającego procesu powłoki)Najpierw wydrukuj PID bieżącej powłoki:
Źródło skryptu:
Uruchom skrypt, zwróć uwagę na PID:
Źródło ponownie:
Wykonaj ponownie:
Widać, że pozyskiwanie skryptu odbywa się w tym samym procesie, a wykonanie skryptu powoduje utworzenie nowego procesu za każdym razem. Ten nowy proces to nowa powłoka, która została stworzona do wykonania skryptu. Pozyskanie skryptu nie tworzy nowej powłoki, a zatem PID pozostaje taki sam.
streszczenie
Zarówno wyszukiwanie, jak i wykonywanie skryptu spowoduje uruchamianie poleceń w skrypcie wiersz po wierszu, tak jakbyś wpisywał te polecenia ręcznie wiersz po wierszu.
Różnice są następujące:
Użyj źródła, jeśli chcesz, aby skrypt zmienił środowisko w aktualnie uruchomionej powłoce. użyj wykonać inaczej.
Zobacz też:
źródło
source myscript.sh
a. myscript.sh
?Wykonanie skryptu powoduje uruchomienie go w osobnym procesie potomnym, tzn. W celu przetworzenia skryptu wywoływana jest osobna instancja powłoki. Oznacza to, że żadnych zmiennych środowiskowych itp. Zdefiniowanych w skrypcie nie można aktualizować w powłoce nadrzędnej (bieżącej).
Pozyskanie skryptu oznacza, że jest on analizowany i wykonywany przez samą bieżącą powłokę. To tak, jakbyś wpisał treść skryptu. Z tego powodu skrypt nie musi być wykonywalny. Ale oczywiście musi być wykonywalny.
Jeśli masz argumenty pozycyjne w bieżącej powłoce, są one niezmienione.
Więc jeśli mam plik
a.sh
zawierający:i robię:
Dostaję coś takiego:
Natomiast:
daje mi:
Mam nadzieję, że to pomaga.
źródło
pozyskiwanie jest zasadniczo takie samo, jak wpisywanie każdej linii skryptu w wierszu polecenia pojedynczo ...
Wykonanie rozpoczyna nowy proces, a następnie uruchamia każdą linię skryptu, modyfikując tylko bieżące środowisko o to, co zwraca.
źródło
Oprócz powyższego wykonanie skryptu
./myscript
wymaga uprawnień do wykonywania skryptu myscript, podczas gdy pozyskiwanie nie wymaga uprawnień do wykonywania. Dlatego wcześniejchmod +x myscript
nie jest to wymaganesource myscript
źródło
bash myscript
.Pozyskiwanie zawiera wszystkie dodatkowe zmienne zdefiniowane w skrypcie.
Więc jeśli masz konfiguracje lub definicje funkcji, powinieneś je pobrać, a nie wykonać. Wykonania są niezależne od środowiska rodziców.
źródło
Jeśli dobrze pamiętam, wykonanie skryptu uruchamia plik wykonywalny w
#!
wierszu z plikiem skryptu jako argumentem (zazwyczaj uruchamianie nowej powłoki i efektywne pozyskiwanie skryptu do nowej powłoki, jak w przypadku#!/bin/sh
);podczas gdy pozyskiwanie skryptu powoduje wykonanie każdego wiersza w bieżącym środowisku powłoki, co jest przydatne do mutowania bieżącej powłoki (na przykład umożliwiając zdefiniowanie funkcji powłoki i eksport zmiennych środowiskowych).
źródło
source
polecenie wykonuje podany skrypt (uprawnienie do wykonywania nie jest obowiązkowe ) w bieżącym środowisku powłoki, natomiast./
wykonuje podany skrypt wykonywalny w nowej powłoce.Sprawdź również tę odpowiedź, na przykład: https://superuser.com/a/894748/432100
źródło