Опция ssh ConnectTimeout

Я использую ssh для запуска некоторых команд для нескольких удаленных ip-соединений для цикла. В основном он выполняет те же команды для списка IP-адресов. Некоторые из IP-адресов могут быть недоступны, поэтому я использовал параметр ConnectTimeout. Но мой script не работал так, как я хотел. На самом деле он застрял в первом недостижимом IP вместо того, чтобы пробовать следующий IP-адрес в моем списке. Вот блок моего кода:

for ip in ${IP} ; do
    ssh  -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=10 -l ${USERNAME} ${SCRIPT_HOST} "${COMMAND} -i $ip || echo timeout" >> ./myscript.out
done

Он отлично работает для достижимых IP-адресов, но если определенный IP-адрес отключен, он ждет некоторое время (более 10 секунд, возможно, 35-40 секунд) и отобразит сообщение об ошибке на моем терминале:

ERROR connecting : Connection timed out

Так что мне интересно, какой вариант я использовал неправильно.

Спасибо.

Ответ 1

Ваше использование ConnectTimeout верное, поэтому неясно, почему он истекает только через 30 и более секунд.

Здесь, как бы я изменил ваш script, чтобы полностью избежать проблемы с таймаутом:

  • Используйте GNU parallel для одновременного подключения к нескольким целевым узлам.
  • Используйте параметр -f для SSH, чтобы обработать его в фоновом режиме.

Вот решение с параллельной GNU, одновременно работающее не более 50 подключений:

parallel --gnu --bg --jobs 50 \
ssh -o BatchMode=yes \
    -o StrictHostKeyChecking=no \
    -o ConnectTimeout=10 \
    -l ${USERNAME} \
    {} \
    "${COMMAND} -i {} || echo timeout" \
::: ${IP}

parallel <command> ::: <arguments> будет выполняться <command> <argument> много раз параллельно, разбивая список <arguments>. Заполнитель для <argument> равен {}.

Используйте parallel --jobs n, чтобы ограничить количество параллельных соединений.

Ответ 2

Тайм-аут соединения - это когда вы уже установили соединение, и если соединение остается бездействующим для этого количества времени в секундах, то оно отключится (это значит, что вы также не активировали параметр ssh KEEP_ALIVE, который предотвращает соединение от вечного простоя).

Причина, по которой требуется 30 секунд, прежде чем вы получите тайм-аут, - это внутренний таймер протокола TCP, который пытается подключиться на этот промежуток времени и вернуть это сообщение об ошибке, которое он не может подключиться к серверу sftp. Это не происходит из ssh.