Kiedy użyję exit
polecenia w skrypcie powłoki, skrypt zakończy terminal (monit). Czy istnieje sposób na zakończenie skryptu, a następnie pozostanie w terminalu?
run.sh
Oczekuje się, że mój skrypt zostanie wykonany bezpośrednio z innego źródła lub z innego skryptu.
EDYCJA: Aby być bardziej szczegółowym, istnieją dwa skrypty run2.sh
jako
...
. run.sh
echo "place A"
...
i run.sh
jak
...
exit
...
kiedy . run2.sh
go exit
mijam , a jeśli wpada w kodod run.sh
, chcę, aby zatrzymał się na terminalu i pozostał tam. Ale przy użyciu exit
cały terminal zostaje zamknięty.
PS: Próbowałem użyć return
, ale echo
kodeline nadal będzie wykonywany ....
exit 0
do zakończenia skryptu po sukcesie, po uruchomieniu skryptu np:./test.sh
powinieneś zobaczyć wynik, ale konsola pozostanie otwarta.shell
polecenia, które faktycznie otwiera terminal powłoki. Jednak z własnego doświadczenia wynika, że tak się nie dziejeexit
. Wyjście zwykle zwraca kontrolę nad skryptem nadrzędnym.Odpowiedzi:
„Problem” naprawdę polega na tym, że pozyskujesz i nie wykonujesz skryptu. Gdy źródło pliku, jego zawartość zostanie wykonana w bieżącej powłoce, zamiast odradzania podpowłoki. Więc wszystko, łącznie z wyjściem, wpłynie na bieżącą powłokę.
Zamiast używać
exit
, będziesz chciał użyćreturn
.źródło
runs.sh
@ruakh, ma lepszą odpowiedź na to pytanie.sh <script>
lubbash <script>
jeśli ktoś chce uruchomić skrypt i zakończyć w pewnym momencieTak; możesz użyć
return
zamiastexit
. Jego głównym celem jest powrót z funkcji powłoki, ale jeśli użyjesz jej wsource
skrypcie -d, ona zwróci z tego skryptu.Zgodnie z §4.1 „Wbudowane powłoki Bourne'a” podręcznika Bash Reference Manual :
źródło
return
można używać TYLKO z funkcji. Jeśli użyjesz goreturn
i wykonasz jako skrypt powłoki (np.sh run.sh
),return: can only
Bashreturn
to nie zadziała, jeśli skrypt zostanie uruchomiony jako skrypt powłoki i nie zostanie wykonany przez. (lubsource
). BTW, gdzie mogę znaleźć dokumentsource -d
?Zamiast uruchamiać skrypt za pomocą
. run2.sh
, możesz go uruchomić za pomocąsh run2.sh
lubbash run2.sh
Zostanie uruchomiona nowa podpowłoka, aby uruchomić skrypt, zostanie ona zamknięta na końcu skryptu, pozostawiając otwartą drugą powłokę.
źródło
sh "." run2.sh
?Możesz dodać dodatkową komendę exit po instrukcji / komendzie return, aby działała w obu przypadkach, wykonując skrypt z wiersza komend i pozyskując go z terminala.
Przykładowy kod wyjścia w skrypcie:
Linia z
exit
poleceniem nie będzie wywoływana, gdy skrypt zostanie pobrany poreturn
poleceniu.Podczas wykonywania skryptu
return
polecenie podaje błąd. Dlatego pomijamy komunikat o błędzie, przekazując go do/dev/null
.źródło
Właściwie myślę, że możesz być zdezorientowany tym, jak uciekasz
run a script
.Jeśli użyjesz
sh
do uruchomienia skryptu, powiedzmy,sh ./run2.sh
nawet jeśli osadzony skrypt kończy się naexit
, okno terminala nadal pozostanie.Jeśli jednak użyjesz
.
lubsource
, okno terminala również się zamknie / zamknie, gdy indeks dolny się skończy.Aby uzyskać więcej informacji, zobacz Jaka jest różnica między używaniem
sh
asource
?źródło
To tak, jakbyś umieścił funkcję uruchamiania w skrypcie run2.sh. Używasz kodu wyjścia w trakcie uruchamiania, podczas gdy źródłowy plik run2.sh znajduje się w bash tty. Jeśli funkcja run daje moc wyjścia ze skryptu i daje run2.sh moc wyjścia z terminatora. Zatem, ponieważ funkcja Run ma moc, aby wyjść z teminatora.
W każdym razie zgadzam się z Kazem, że to problem projektowy.
źródło
Miałem ten sam problem i z powyższych odpowiedzi oraz z tego, co zrozumiałem, ostatecznie działało dla mnie:
Mieć linię shebang, która wywołuje zamierzony skrypt, na przykład
#!/bin/bash
służybash
do wykonania skryptuMam skrypty z oboma rodzajami shebang. Z tego powodu używanie
sh
lub.
nie było niezawodne, ponieważ prowadziło to do błędnego wykonania (na przykład, gdy skrypt nie działa poprawnie)Odpowiedź brzmiała więc:
(chmod +x file.sh)
Wywołaj go bezpośrednio bez żadnego
sh
lub.
(./myscript.sh)
Mam nadzieję, że to pomoże komuś z podobnym pytaniem lub problemem.
źródło
Myślę, że tak się dzieje, ponieważ używasz go w trybie źródłowym z kropką
Powinieneś uruchomić to w podpowłoce:
„source” http://ss64.com/bash/source.html
źródło
. myscript.sh
działa, nie potrzebujesz pełnej ścieżki do skryptu . Co najwyżej możesz potrzebować./myscript.sh
.Jak słusznie zauważyli inni , słuszne jest, że skrypty źródłowe i wykonywane używają
return
vs.,exit
aby utrzymać tę samą sesję otwartą.Oto pokrewna wskazówka, jeśli kiedykolwiek potrzebujesz skryptu, który powinien utrzymywać sesję otwartą, niezależnie od tego, czy jest ona pozyskiwana, czy nie.
Poniższy przykład można uruchomić bezpośrednio jak
foo.sh
lub pozyskać jak. foo.sh
/source foo.sh
. W obu przypadkach sesja pozostanie otwarta po „wyjściu”.$@
Łańcuch jest przekazywany tak, że funkcja ma dostęp do argumentów zewnętrznej skryptu.Wynik końcowy:
Może to być przydatne do szybkiego testowania zmian skryptu w jednym terminalu przy jednoczesnym trzymaniu paczki złomu pod głównym
exit
/return
podczas pracy. Może także sprawić, że kod stanie się bardziej przenośny w pewnym sensie (jeśli masz mnóstwo skryptów, które można wywoływać na różne sposoby lub nie), chociaż jest o wiele mniej niezręczny w użyciureturn
iexit
tam, gdzie jest to właściwe.źródło
jeśli twój emulator terminala nie ma tego
-hold
, możesz zdezynfekować skrypt pochodzący od źródła i zatrzymać terminal za pomocą:w przeciwnym razie możesz użyć
$TERM -hold -e script
źródło
Zwróć również uwagę na zwrot z oczekiwaną wartością zwrotu. W przeciwnym razie, jeśli użyjesz wyjścia, gdy napotkasz wyjście, wyjdzie ono z podstawowej powłoki, ponieważ źródło nie tworzy innego procesu (instancji).
źródło
Aby napisać skrypt, który jest bezpieczny być uruchamiany zarówno jako skrypt powłoki lub pozyskiwane jako plik rc, skrypt może sprawdzić i porównać
$0
i$BASH_SOURCE
i ustalić, czyexit
można bezpiecznie stosować.Oto krótki fragment kodu do tego
źródło
1) Wyjście 0 wyjdzie ze skryptu, jeśli się powiedzie.
2) Wyjście 1 wyjdzie ze skryptu, jeśli jest to błąd.
Możesz wypróbować powyższe dwa w oparciu o twoje wymagania.
źródło