2012-03-09 13 views
121

Kiedy używam polecenia exit w skrypcie powłoki, skrypt zakończy terminal (monit). Czy istnieje sposób na zakończenie skryptu, a następnie pozostanie w terminalu?Dowolny sposób na zamknięcie skryptu bash, ale nie opuszczanie terminala

Oczekuje się, że mój skrypt run.sh zostanie wykonany bezpośrednio lub z innego skryptu.

EDIT: Aby być bardziej konkretne, istnieją dwa skrypty run2.sh jak

... 
. run.sh 
echo "place A" 
... 

i run.sh jako

... 
exit 
... 

gdy uruchomię go przez . run2.sh, a jeśli to hit exit codeline w run.sh Chcę, żeby zatrzymał się w terminalu i tam został. Ale używając exit, cały terminal zostanie zamknięty.

PS: próbowałem użyć return, ale echo codeline będzie nadal pobiera wykonywane ....

+3

Naprawdę, naprawdę, naprawdę muszę zapytać: dlaczego używasz wyjścia w skryptach źródłowych? –

+3

Polecenie exit nie powinno powodować zakończenia sesji terminalowej/logowania. jeśli użyjesz 'exit 0' do zakończenia skryptu po powodzeniu, po uruchomieniu skryptu ex:'./test.sh' powinieneś zobaczyć dane wyjściowe, ale konsola pozostanie otwarta. –

+0

Można użyć polecenia 'shell', które otwiera w rzeczywistości terminal powłoki. Moje własne doświadczenie jest jednak takie, że nie dzieje się tak z 'exit'. Wyjście zwykle przywraca kontrolę nad skryptem nadrzędnym. –

Odpowiedz

173

"Problem" polega na tym, że pozyskujesz i nie wykonujesz skryptu. Gdy pobierzesz plik, jego zawartość zostanie wykonana w bieżącej powłoce, zamiast tworzenia podpowłoki. Zatem wszystko, łącznie z zakończeniem, wpłynie na bieżącą powłokę.

Zamiast używać exit, należy użyć return.

+1

Oto inne wytłumaczenie, które uważam za pomocne: http://askubuntu.com/a/53179/148337 – 3cheesewheel

+0

Chociaż jest poprawne, nie jest to dobra odpowiedź. Ignoruje on, że skrypt wywołujący może zadeklarować zmienne lub funkcje, do których skrypt ten potrzebuje dostępu. Lepiej wyjaśnić, jak ustawić kod powrotu, a następnie przetworzyć go w 'runs.sh' @ruakh ma lepszą odpowiedź na to pytanie. – MikeSchinkel

+3

Co się stanie, jeśli funkcja jest połączeniem zagnieżdżonym? tj. wywołania b, b wywołania c, c chcą natychmiast wyjść z aib. – Michael

-2

1) exit 0 wyjdzie skryptu jeśli jest to sukces.

2) wyjście 1 wyjdzie ze skryptu, jeśli jest to błąd.

Możesz wypróbować powyższe dwa oparte na ur req.

29

Tak; możesz użyć return zamiast exit. Jego głównym celem jest powrót z funkcji powłoki, ale jeśli użyjesz jej w skrypcie source -d, to ona powróci z tego skryptu.

jako §4.1 "Bourne Shell Builtins" of the Bash Reference Manual mówi:

 return [n] 

Ponieważ funkcja powłoki na wyjściu z wartością powrotu n. Jeśli nie podano wartości n, wartość zwracana jest stanem wyjściowym ostatniego polecenia wykonanego w funkcji przez . ten może być również użyty do zakończenia wykonywania skryptu wykonywane z . (lub source) wbudowanego polecenia, powrót albo n lub stan wyjścia ostatniego polecenia zawartej w skrypcie jak stan wyjście skryptu . Każde polecenie związane z pułapką RETURN jest wykonywane przed wykonaniem wznowienia po funkcji lub skrypcie. Status powrotu jest niezerowy, jeśli return jest używany poza funkcją , a nie podczas wykonywania skryptu przez . lub source.

2

To jest tak, jak umieścisz funkcję run w swoim skrypcie run2.sh. Używasz kodu wyjścia podczas uruchamiania, a źródłowy plik run2.sh w bash tty. Jeśli funkcja run nadaje jej moc do opuszczenia skryptu i daje run2.sh jego moc do wyjścia z terminatora. Następnie, ponieważ funkcja run ma moc wyjścia z teminatora.

#! /bin/sh 
    # use . run2.sh 

    run() 
    { 
     echo "this is run" 
     #return 0 
     exit 0 
    } 

    echo "this is begin" 
    run 
    echo "this is end" 

W każdym razie, zgadzam się z Kazem, to problem z projektowaniem.

0

jeśli emulator terminala nie ma -hold można zdezynfekować się pozyskiwaniem skrypt i przytrzymaj terminal:

#!/bin/sh 
sed "s/exit/return/g" script >/tmp/script 
. /tmp/script 
read 

inaczej można użyć $TERM -hold -e script

2

myślę, że to się dzieje, ponieważ używasz to od trybu źródłowego z kropką

. myscript.sh 

należy uruchomić że w podpowłoce:

/full/path/to/script/myscript.sh 

'źródło' http://ss64.com/bash/source.html

+0

Nie potrzebujesz pełnej ścieżki do skryptu, jeśli '. myscript.sh' działa. Co najwyżej możesz potrzebować './Myscript.sh'. –

0

Również upewnić się, aby powrócić do wartości oczekiwanej powrotnej. Inaczej, jeśli użyjesz wyjścia, gdy napotkasz wyjście, wyjdzie ono z twojej powłoki bazowej, ponieważ źródło nie tworzy innego procesu (instancji).

9

Zamiast uruchamiać kod za pomocą . run2.sh można uruchomić skrypt przy użyciu sh run2.sh lub bash run2.sh
Nowa instancja zostanie otwarte, aby uruchomić skrypt zostanie on zamknięty na końcu skryptu pozostawiając drugą powłokę otwierane. `

+0

Jeśli tak, to dlaczego drugi parametr "sh". " run2.sh'? – H0WARD

+0

@ H0WARD Masz rację, zapomniałem usunąć kropki. Edytowałem odpowiedź teraz. –

+0

PO wyraźnie określa źródło jako wymaganie. –

0

To prawda, że ​​skrypty oparte na źródle kontra skrypty używają return w porównaniu do exit, aby utrzymać tę samą sesję otwartą, co inni zauważyli.

Oto podobna wskazówka, jeśli kiedykolwiek chcesz skrypt, który powinien zachować otwartą sesję, niezależnie od tego, czy jest ona dostępna.

Poniższy przykład można uruchomić bezpośrednio, tak jak foo.sh lub pochodzić tak jak . foo.sh/source foo.sh. Tak czy inaczej, sesja będzie otwarta po "wyjściu". Ciąg [email protected] jest przekazywany, aby funkcja miała dostęp do argumentów skryptu zewnętrznego.

#!/bin/sh 
foo(){ 
    read -p "Would you like to XYZ? (Y/N): " response; 
    [ $response != 'y' ] && return 1; 
    echo "XYZ complete (args [email protected])."; 
    return 0; 
    echo "This line will never execute."; 
} 
foo "[email protected]"; 

wynik Terminal:

$ foo.sh
$ chciałbyś XYZ? (T/N): n
$. foo.sh
$ Czy chcesz XYZ?(T/N): n
$ |
(okno terminalu pozostaje otwarty i przyjmuje dodatkowe wejście)

To może być przydatna do szybkiego testowania zmian skryptów w jednym terminalu, zachowując kilka kodu złomu pod głównym exit/return podczas pracy. Mogłoby to również uczynić kod bardziej przenośnym w pewnym sensie (jeśli masz mnóstwo skryptów, które mogą lub nie mogą być wywoływane na różne sposoby), ale jest to o wiele mniej przylegające, aby po prostu użyć return i exit, gdzie jest to właściwe.

Powiązane problemy