Як зробити ssh з таймаутом у сценарії?


173

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

Будь-яка ідея, як це зробити?


Це, мабуть, має бути закрито, щоб відповідати закриттю повного дубліката цього, як зменшити значення тайм-ауту з'єднання ssh [закрито]
Murmel

Якщо ви переадресувались тут лише на те, щоб "залишитися більше часу на sshсеансі" (питання "Як збільшити час очікування з'єднання SSH?"), Це неправильне місце . Відповідь знаходиться за цим посиланням про ssh-timeout .
Пітер Краус

Відповіді:


288
ssh -o ConnectTimeout=10  <hostName>

Де 10 - час у секундах. Цей час очікування застосовується лише до створення з'єднання.


4
ConnectTimeout встановлює лише тайм-аут під час налаштування з'єднання, правда?
Aurélien Ooms

10
Це насправді не працює для того, щоб "віддалений хост займає нескінченний час для запуску": "ssh -o ConnectTimeout = 5 хоста" сон 10 "" чекає 10 секунд, а не 5.
Ferry Boender

109

Використовуйте -o ConnectTimeoutі -o BatchMode=yes -o StrictHostKeyChecking=no.

ConnectTimeout утримує сценарій від зависання, BatchMode утримує його від зависання з невідомим хостом, ТАК для додавання до відомих_хостів, а StrictHostKeyChecking додає відбиток пальців автоматично.

**** ПРИМІТКА **** "StrictHostKeyChecking" призначався лише для внутрішніх мереж, де ви довіряєте своїм господарям. Залежно від версії клієнта SSH, "Ви впевнені, що хочете додати свій відбиток пальців", це може призвести до того, що клієнт повіситься на невизначений час (переважно старі версії, що працюють на AIX). Більшість сучасних версій не страждають від цього питання. Якщо вам доведеться мати справу з відбитками пальців з декількома хостами, я рекомендую підтримувати файл known_hosts за допомогою якогось інструменту управління конфігурацією, наприклад ляльковий / ansible / шеф-кухар / сіль / тощо.


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

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

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 ).
личинка

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 = <secs>
тож клієнт SSH надсилатиме нульовий пакет серверу <secs>щосекунди, лише щоб зберегти з'єднання живим. У Linux це також можна встановити у всьому світі /etc/ssh/ssh_configабо на кожного користувача ~/.ssh/config.


4
Це звучить як протилежне тому, що запитує запитання.
Давор Кубраніч

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
Едуардо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.