Próbuję zautomatyzować kilka typowych zadań, które wykonuję SSH do zdalnego serwera. W tym celu używam PuTTY i jego opcji „polecenia zdalnego” (Połączenie> SSH) w kilku zapisanych sesjach. Moje zdalne polecenie wygląda mniej więcej tak:
~/scripts/test; $SHELL -l
Wykonywany skrypt różni się w zależności od zapisanej sesji i wykonuje różne zadania. $SHELL -l
utrzymuje sesję PuTTY aktywną po zakończeniu wykonywania skryptu.
Wszystko to działa idealnie dla większości skryptów, które uruchamiam. Mam jednak taki, który używa pętli while do wykonania szeregu poleceń, dopóki nie zakończy się kombinacją Ctrl + C. Skrypt uruchamia się dobrze, ale powłoka PuTTY nie pozostaje aktywna po zakończeniu. $SHELL -l
nie wydaje się być wykonywany.
Przykładowy skrypt z takim zachowaniem jest następujący:
while true; do
echo "."
sleep 2
done
Poniższe działa dobrze wykonane ręcznie, widzę oczekiwane dane wyjściowe z drugiego polecenia:
~/scripts/test; echo "done"
Jednak drugie polecenie „polecenia zdalnego” PuTTY nie jest wykonywane. Rzeczywiście, jeśli zmienię komendę zdalną na „an” echo
, nie zostanie ona wyświetlona.
~/scripts/test; echo "done"; $SHELL -l
Myślę więc, że moje pytanie brzmi: dlaczego drugie polecenie na liście nie jest wykonywane przez polecenie zdalne, podczas gdy jest uruchamiane ręcznie? A co ważniejsze, co mogę z tym zrobić?
Jeśli to istotne, używam PuTTY na Ubuntu 14.04.
ssh
(OpenSSH)? To powinno być domyślnie zainstalowane na Ubuntu. Lub jeśli naprawdę musisz korzystać z PuTTY, użyjplink
, który jest specjalnie zaprojektowany do automatyzacji.Odpowiedzi:
Kiedy uruchomisz
putty
lubssh
- nie sądzę, żeby w tym kontekście istniała jakaś różnica - z poleceniem do uruchomienia w systemie zdalnym, zdalny serwer ssh uruchamia polecenie jako polecenie powłoki:Więc masz
bash
instancję w zdalnym systemie wykonującą ten potok. Masz także innąbash
instancję uruchomioną przez pierwszą instancję, która wykonuje ten skrypt „testowy”.Po wpisaniu Control-C
putty
wysyła znak do zdalnego systemu, gdzie jest interpretowany przez TTY jako znak przerwania. Powoduje to wysłanie SIGINT (sygnał przerwania) do procesów dołączonych do TTY. Przerywa to oba procesy powłoki, powodując ich zamknięcie. Chcesz, aby instancja powłoki nadrzędnej ignorowała SIGINT.Polecenie bash, aby zignorować SIGINT, to:
Aby wyłączyć SIGINT dla potoku, zmień oryginalne polecenie na:
Ale to wyłącza SIGINT również dla procesów potomnych, co uczyniłoby skrypt „testowy” odpornym na Ctrl-C. Musisz więc ponownie włączyć SIGINT dla skryptu testowego. Polecenie to brzmi:
Możesz dodać ten wiersz do samego skryptu testowego lub możesz dodać go do potoku:
Teraz, kiedy naciśniesz Ctrl-C, powinieneś przerwać proces „testowy”, ale nie proces nadrzędny, który wykonuje potok poleceń.
Możesz to przetestować bez użycia putta lub ssh. Wystarczy uruchomić te polecenia i nacisnąć Ctrl-C podczas wykonywania „uśpienia”:
źródło
ctrl + c dla komendy putty faktycznie przerywa sesję ssh, więc należy się spodziewać, że nie wykonuje ona pozostałych komend zdalnych. Jeśli Twoim celem jest, aby sesja nadal była aktywna, Twoja nieskończona pętla powinna wystarczyć.
źródło