SSH викликає зупинку циклу


30

Нарешті мені вдалося усунути проблему, з якою я боровся вже кілька тижнів. Я використовую SSH з "авторизованими клавішами" для віддаленого запуску команд. Все добре, за винятком випадків, коли я це роблю в певний час. Цикл завершується після завершення будь-якої ітерації командою ssh.

Довгий час я думав, що це якась дивна дивність, але зараз я виявив, що баш насправді поводиться однаково.

Невеликий зразок програми для відтворення проблеми. Це дистильовано з більшої реалізації, яка робить знімки та реплікує їх серед вузлів кластера.

#!/bin/bash

set -x

IDTAG=".*zone"
MARKER="mark-$(date +%Y.%m.%d.%H.%M.%S)"
REMOTE_HOST=sol10-target
ZFSPARENT=rpool

ssh $REMOTE_HOST zfs list -t filesystem -rHo name,mounted $ZFSPARENT | grep "/$IDTAG    " > /tmp/actionlist

#for RMT_FILESYSTEM in $(cat /tmp/actionlist)
cat /tmp/actionlist | while read RMT_FILESYSTEM ISMOUNTED
do
   echo ${RMT_FILESYSTEM}@${MARKER}
   [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
   echo Remote Command Return Code: $?
done

(Зверніть увагу, що в виразі grep search є символ TAB відповідно до визначення поведінки параметра "-H" у списку zfs.)

У моєму зразку є декілька файлових систем ZFS для кореня, де всі "зони" мають свою кореневу файлову систему на наборі даних, схожої на

POOL / зони / app1zone
POOL / зони / group2 / app2zone

тощо.

Вищеописаний цикл повинен створити знімок для кожного з обраних наборів даних, але замість цього він працює лише на першому, а потім на виході.

Про те, що програма знаходить потрібну кількість наборів даних, можна легко підтвердити, перевіривши файл "/ tmp / actionlist" після існування сценарію.

Якщо команду ssh замінити, наприклад, командою echo, то цикл проходить через усі вхідні рядки. Або мій улюблений - додайте «відлуння» до команди, що ображає.

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

Зараз я на 99,999% впевнений, що лише ті петлі з командами ssh створюють мені проблеми!

Зауважте, що ітерація, в якій виконується команда ssh, завершується! Це так, як якщо б дані, накладені на цикл while, раптом втрачаються ... Якщо перші кілька вхідних рядків не виконують команду ssh, цикл продовжується, поки він фактично не виконує команду SSH.

У моєму ноутбуці, де я тестую це, у мене є два VM Solaris 10 з лише двома-трьома наборами наборів даних, але те ж саме відбувається у великих системах SPARC, де це покликане жити, і є безліч наборів даних.


7
SSH може читати зі стандартного введення, з'їдаючи ваше actionlist. Спробуйте перенаправити стандартний вхід ssh на/dev/null
BatchyX

Я спробую це. Хочу додати, що введення ssh в обгортку не допомагає ....
Йохан

Ви праві. Як я цього не бачив !?
Йоган

@BatchyX Я думаю, що ваш коментар кваліфікується як відповідь.
CVn

Я погоджуюсь, що хотів би "прийняти" відповідь, тому якщо @BatchyX зможе її перетворити як таку, я це зроблю.
Йоган

Відповіді:


43

SSH, можливо, читається зі стандартного введення, з'їдає ваш список дій. Спробуйте перенаправити стандартний вхід ssh на / dev / null:

ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER} </dev/null

Як правило, під час виконання команд, які можуть перешкоджати стандартному вводу під while readциклом -style, я люблю загортати все тіло циклу в дужки:

cat /tmp/uuoc | while read RMT_FILESYSTEM ISMOUNTED
do {
    echo ${RMT_FILESYSTEM}@${MARKER}
    [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
    echo Remote Command Return Code: $?
} < /dev/null; done

3
Подвійний дивовижний, по-перше, про специфічне використання фігурних брекетів ... яких я за 20 років сценаріїв ніколи не зустрічав (принаймні, не те, що я пам’ятаю.) І для висновку ууоку. FWIW (і на власний захист) я іноді роблю виняток і додаю зайві заяви про котів заради читабельності! Мені подобається цей форум, тому що я раптом знову вчу нові речі! Конкретніше мені подобається додавати перенаправлення до початку рядків, як у цьому випадку, але на форумах, які, здається, плутають питання, викликаючи меншу кількість корисних відповідей!
Йоган

Я намагався вирішити різницю між {...} та (...) сторінкою ksh man пише, що {...} - це спеціальні ключові слова, розпізнавані лише на початку командного рядка. Але є й інша відмінність ... ( </tmp/file [ -z "$SOMEVAR" ] && awk '{print "X", $0}' )відрізняється однаковою з фігурними брекетами. Я маю на увазі з точки зору виробленої продукції, а не про те, що фіксуючий фігурний брекет повинен бути на новій лінії ...
Йохан

5
Крім того, ssh OpenSSH має -nопцію, яка змушує (ефективно) повторно відкривати свій stdin з / dev / null.
Кріс Джонсен

Будь-які обхідні шляхи для використання sudoз командою всередині циклу?
bonh

Я звик використовувати -n з віків, і в якийсь момент втратив звичку .... і тепер я знову знаю, чому я це зробив, через деякий час провів копання ...
Флоріан Хейгл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.