Как сделать SSH с таймаутом в скрипте?


173

Я выполняю сценарий подключения через SSH без пароля на удаленном хосте. Я хочу установить тайм-аут, чтобы, если удаленный хост работал бесконечно долго, я хотел выйти из этого сеанса ssh и продолжить другие строки в моем скрипте sh.

Есть идеи, как это сделать?


Это, вероятно, должно быть закрыто, чтобы соответствовать закрытию полного дубликата о том, как уменьшить значение тайм-аута соединения ssh [закрыто]
Murmel

Если вы перенаправили сюда только «остаться в sshсеансе больше времени » (вопрос «Как увеличить время ожидания соединения SSH?»), Это неправильное место . Ответ по этой ссылке о ssh-timeout .
Питер Краусс

Ответы:


288
ssh -o ConnectTimeout=10  <hostName>

Где 10 - время в секундах. Этот тайм-аут относится только к созданию соединения.


4
ConnectTimeout только устанавливает тайм-аут на настройку соединения, верно?
Орельен Уомс,

10
Это на самом деле не работает, поскольку «удаленному хосту требуется бесконечное время для запуска»: «ssh -o ConnectTimeout = 5 хост« sleep 10 »» ждет 10 секунд, а не 5.
Ferry Boender

109

Используйте -o ConnectTimeoutи -o BatchMode=yes -o StrictHostKeyChecking=no.

ConnectTimeout предотвращает зависание скрипта, BatchMode предотвращает его зависание при неизвестном хосте, YES для добавления в known_hosts, а StrictHostKeyChecking автоматически добавляет отпечаток пальца.

**** ПРИМЕЧАНИЕ **** «StrictHostKeyChecking» предназначался только для внутренних сетей, где вы доверяете своим хостам. В зависимости от версии клиента SSH сообщение «Вы уверены, что хотите добавить свой отпечаток» может привести к зависанию клиента на неопределенное время (в основном это старые версии, работающие в AIX). Большинство современных версий не страдают от этой проблемы. Если вам приходится иметь дело с отпечатками пальцев на нескольких хостах, я рекомендую поддерживать файл known_hosts с помощью какого-либо инструмента управления конфигурацией, такого как puppet / ansible / chef / salt / etc.


11
Это не только -o StrictHostKeyChecking=noне решает вопрос, но это ужасная идея, если вы заботитесь о безопасности, что может быть причиной того, что вы используете SSH в первую очередь.
Дольф

9
Полезно указать возможные последствия для безопасности -o StrictHostKeyChecking = no. Однако это предотвратит зависание скрипта во время выполнения.
Даг

2
ПРЕДУПРЕЖДЕНИЕ!!!! Как писал @Dolph, НЕ используйте, StrictHostKeyChecking=noесли вы вообще заботитесь о безопасности. @Doug: скрипт не будет зависать - он просто будет настаивать на том, чтобы вы сначала подключились к удаленному хосту вручную, чтобы он узнал хост. Но это защитит вас от атак MITM. Пожалуйста, отредактируйте этот ответ, чтобы отразить это, так как это очень опасный совет. И это даже не просили.
Johndodo

2
Обновил мой ответ. По моему опыту, это может привести к зависанию некоторых клиентов.
Дуг

50

попробуй это:

timeout 5 ssh user@ip

timeout выполняет команду ssh (с аргументами) и отправляет SIGTERM, если ssh не возвращается через 5 секунд. для получения более подробной информации о тайм-ауте, прочитайте этот документ: http://man7.org/linux/man-pages/man1/timeout.1.html

или вы можете использовать параметр ssh:

ssh -o ConnectTimeout=3 user@ip

4
Если вы ищете эту команду на Mac, попробуйте brew install coreutilsи затем используйте gtimeout (источник: stackoverflow.com/questions/3504945/timeout-command-on-mac-os-x ).
Larcher

3
Это может не делать то, что вы хотите. Рассмотрим команду. timeout 3s ssh user@server 'sleep 5; echo blarg >> /tmp/blarg' Это убивает процесс на стороне клиента SSH, но / tmp / blarg по-прежнему изменяется на удаленном сервере. Это означает, что, если вы выполняете на удаленном сервере невыполненную работу с интенсивным использованием ЦП, вы будете пропускать процессы.
Джейми Дэвис

1
@JamieDavis как насчет ssh user @ server 'timeout 5s sleep 10'?
FilipR

18

Вы также можете связаться с флагом

-o ServerAliveInterval = <сек>
поэтому SSH-клиент будет отправлять нулевой пакет на сервер каждую <secs>секунду, чтобы поддерживать соединение. В Linux это также может быть установлено глобально /etc/ssh/ssh_configили для каждого пользователя ~/.ssh/config.


4
Это звучит как противоположность того, что просит вопрос.
Davor Cubranic

1

Если все остальное терпит неудачу (включая отсутствие timeoutкоманды), концепция в этом сценарии оболочки будет работать:

 #!/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

Ну, вы могли бы использовать nohup для запуска того, что вы используете в «неблокирующем режиме». Таким образом, вы можете просто продолжать проверять, запускается ли то, что должно было выполняться, иначе выходите.

nohup ./my-script-that-may-take-long-to-finish.sh &
./check-if-previous-script-ran-or-exit.sh
echo "Сценарий закончился 15 февраля 2011 г., 9:20"> /tmp/done.txt

Итак, во втором вы просто проверьте, существует ли файл.


Имеет смысл. но, скрипт, который работает, дает мне некоторый вывод, который отображается на консоли .. как проверить, выполнялся ли мой предыдущий скрипт или завершился? $? или что-нибудь еще?
user57421

Ну, вы можете заставить этот скрипт создать файл, когда закончите. Я добавил комментарий к ответу .... grrr
Eduardo
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.