Jak wykonać ssh z limitem czasu w skrypcie?


173

Wykonuję skrypt łączący się przez SSH bez hasła na zdalnym hoście. Chcę ustawić limit czasu, aby jeśli zdalny host działał w nieskończoność, chcę wyjść z tej sesji ssh i kontynuować inne wiersze w moim skrypcie sh.

Masz jakiś pomysł, jak to zrobić?


Prawdopodobnie powinno to być zamknięte, aby było zgodne z zamknięciem pełnego duplikatu tego, jak zmniejszyć wartość limitu czasu połączenia ssh [zamknięte]
Murmel

Jeśli przekierowałeś tutaj tylko po to, aby „pozostać dłużej w sshsesji” (pytanie „Jak zwiększyć limit czasu połączenia SSH?”), To jest niewłaściwe miejsce . Odpowiedź znajduje się pod tym linkiem o ssh-timeout .
Peter Krauss,

Odpowiedzi:


288
ssh -o ConnectTimeout=10  <hostName>

Gdzie 10 to czas w sekundach. Ten limit czasu dotyczy tylko tworzenia połączenia.


4
ConnectTimeout ustawia tylko limit czasu konfiguracji połączenia, prawda?
Aurélien Ooms

10
To faktycznie nie działa, gdy „zdalny host działa nieskończenie długo”: „ssh -o ConnectTimeout = 5 host 'sleep 10'” czeka 10 sekund, a nie 5.
Ferry Boender

109

Użyj -o ConnectTimeouti -o BatchMode=yes -o StrictHostKeyChecking=no.

ConnectTimeout zapobiega zawieszaniu się skryptu, BatchMode zapobiega zawieszaniu się z nieznanym hostem, TAK, aby dodać do known_hosts, a StrictHostKeyChecking automatycznie dodaje odcisk palca.

**** UWAGA **** Funkcja „StrictHostKeyChecking” była przeznaczona tylko dla sieci wewnętrznych, w których ufasz swoim hostom. W zależności od wersji klienta SSH komunikat „Czy na pewno chcesz dodać odcisk palca” może spowodować zawieszenie się klienta na czas nieokreślony (głównie stare wersje działające w systemie AIX). Większość nowoczesnych wersji nie ma tego problemu. Jeśli masz do czynienia z odciskami palców na wielu hostach, polecam utrzymywanie pliku known_hosts za pomocą jakiegoś narzędzia do zarządzania konfiguracją, takiego jak puppet / ansible / chef / salt / etc.


11
Nie tylko -o StrictHostKeyChecking=nonie rozwiązuje tego pytania, ale jest to okropny pomysł, jeśli zależy Ci na bezpieczeństwie, co może być powodem, dla którego używasz SSH w pierwszej kolejności.
Dolph

9
Dobrze jest zwrócić uwagę na możliwe implikacje dla bezpieczeństwa wynikające z -o StrictHostKeyChecking = no. Jednak zapobiegnie to zawieszaniu się skryptu podczas wykonywania.
Doug,

2
OSTRZEŻENIE!!!! Jak napisał @Dolph, NIE używaj, StrictHostKeyChecking=nojeśli w ogóle zależy Ci na bezpieczeństwie. @Doug: skrypt nie zawiesza się - po prostu będzie wymagał ręcznego ssh do zdalnego hosta za pierwszym razem, aby poznał hosta. Ale ochroni cię przed atakami MITM. Zmień tę odpowiedź, aby to odzwierciedlić, ponieważ w obecnym kształcie jest to bardzo niebezpieczna rada. I nawet o to nie prosili.
johndodo

2
Zaktualizowałem moją odpowiedź. Z mojego doświadczenia wynika, że ​​niektórzy klienci mogą się zawiesić.
Doug,

50

Spróbuj tego:

timeout 5 ssh user@ip

timeout wykonuje polecenie ssh (z argumentami) i wysyła SIGTERM, jeśli ssh nie zwróci po 5 sekundach. Aby uzyskać więcej informacji na temat limitu czasu, przeczytaj ten dokument : http://man7.org/linux/man-pages/man1/timeout.1.html

lub możesz użyć parametru ssh:

ssh -o ConnectTimeout=3 user@ip

4
Jeśli szukasz tego polecenia na komputerze Mac, spróbuj, brew install coreutilsa następnie użyj gtimeout (źródło: stackoverflow.com/questions/3504945/timeout-command-on-mac-os-x ).
larcher

3
To może nie robić tego, co chcesz. Rozważ polecenie timeout 3s ssh user@server 'sleep 5; echo blarg >> /tmp/blarg' To zabija proces po stronie klienta SSH, ale / tmp / blarg nadal jest modyfikowany na serwerze zdalnym. Oznacza to, że jeśli wykonujesz na zdalnym serwerze zadanie mocno obciążające procesor, nastąpi wyciek procesów.
Jamie Davis

1
@JamieDavis a co z ssh user @ server 'timeout 5s sleep 10'?
FilipR

18

Możesz również połączyć się z flagą

-o ServerAliveInterval = <sekundy>
więc klient SSH będzie wysyłał pakiet zerowy do serwera co <secs>sekundę, aby utrzymać połączenie. W Linuksie można to również ustawić globalnie w /etc/ssh/ssh_configlub na użytkownika w ~/.ssh/config.


4
To brzmi jak przeciwieństwo tego, czego wymaga pytanie.
Davor Cubranic

1

Jeśli wszystko inne zawiedzie (w tym brak timeoutpolecenia), koncepcja tego skryptu powłoki zadziała:

 #!/bin/bash
 set -u
 ssh $1 "sleep 10 ; uptime" > /tmp/outputfile 2>&1 & PIDssh=$!
 Count=0
 while test $Count -lt 5 && ps -p $PIDssh > /dev/null
 do
    echo -n .
    sleep 1
    Count=$((Count+1))
 done
 echo ""

 if ps -p $PIDssh > /dev/null
 then
    echo "ssh still running, killing it"
    kill -HUP $PIDssh
 else
    echo "Exited"
 fi

0

Cóż, możesz użyć nohup, aby uruchomić wszystko, co uruchomisz w „trybie nieblokującym”. Możesz więc po prostu sprawdzać, czy cokolwiek miało uruchomić, uruchomiło się, w przeciwnym razie zakończyło.

nohup ./my-script-that-may-take-long-to-finish.sh &
./check-if-previous-script-ran-or-exit.sh
echo "Skrypt zakończył się 15 lutego 2011 o 9:20"> /tmp/done.txt

Więc w drugim sprawdzasz, czy plik istnieje.


Ma sens. ale skrypt, który jest uruchomiony, daje mi jakieś dane wyjściowe, które są wyświetlane na konsoli .. jak sprawdzić, czy mój poprzedni skrypt został uruchomiony lub zamknięty? $? albo coś innego ?
user57421

Cóż, możesz sprawić, że skrypt utworzy plik po zakończeniu. Dodałem komentarz do odpowiedzi .... grrr
Eduardo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.