Перезагрузка нескольких хостов по SSH с циклом while [duplicate]

Существует альтернативный подход для выхода Screenshooter в Xfce. То есть для запуска Screenhooter с ограничением по времени с помощью команды timeout.

Добавьте новый ярлык приложения со следующей командой.

timeout 15 bash -c 'xfce4-screenshooter -r -s $HOME'

Затем нажмите любую клавишу клавиатуры выбор для командной строки. Я использовал клавиши Shift + Print в своем тестировании. Теперь снова нажмите клавиши, чтобы вызвать команду.

Почему эти параметры

-s PATH указывают каталог в PATH, где будет сохранен снимок экрана. Эта опция пропустит диалог, чтобы выбрать действие, то есть сохранить, скопировать в буфер обмена, который отображается перед диалоговым окном «Сохранить как». Это уменьшит взаимодействие пользователя на несколько секунд.

bash -c '... $HOME' - указать переменную окружения Home directory текущего пользователя, используя оболочку bash. Это удобно, а не использовать прямой путь как /home/USERNAME.

Почему эти параметры

Когда timeout достигло продолжительности, указанная команда т.е. Screenshooter будет завершен, независимо от того, был ли снимок сделан и сохранен или иным образом. Для выхода из приложения команда не требует отдельного ярлыка.

Если указанная продолжительность довольно долго ждать, пользователь может:

Изменить продолжительность таймаута с 15 на меньшее значение в секунд. Выйдите немедленно, используя сочетания клавиш для killall xfce4-screenshooter, как предложено @linuxode

. Последнее, по-видимому, является более легким обходным решением, вместо того, чтобы изменять продолжительность таймаута, которая зависит от времени, затраченного пользователем на выбор региона и сохранение скриншота с другим именем, если оно есть. Вот почему я предложил 15 секунды и не меньше этого.

Еще лучше, установите оптимальную продолжительность (ни слишком короткую, ни слишком длинную для ожидания пользователя), и используйте обе обходные пути, которые позволят пользователя «ждать или убить», чтобы выйти из Screenhooter в Xfce.

Отказ от ответственности

Этот ответ предлагает обходное решение, а не определенное решение. Лучшим ответом будет использование клавиши Shift , которая должна работать правильно с Screenhooter в Xfce. Прежде всего, я не уверен, что указанная проблема все еще встречается в Xfce более поздней версии 4.10 или еще.

2
задан 1 December 2017 в 20:00

4 ответа

Наконец, я предполагал, что остальная часть скрипта в порядке. Затем я последовал за комментарием @ dessert и использовал shellcheck, которые привели меня к актуальной проблеме и ее решению:

SC2095: Добавьте < /dev/null, чтобы предотвратить ssh от проглатывания stdin.

Итак, вы должны изменить свой сценарий таким образом:

ssh -p 2222 "$p" 'who -b' < /dev/null | awk '{print $(NF-1)" "$NF}' >> 'file2'

Согласно комментарию @ dessert и спасибо в полезные советы, представленные в комментариях @EliahKagan и shellcheck , полный скрипт может выглядеть так:

#!/bin/bash # Collect the user's input, and if it`s empty set the default values [[ -z "${1}" ]] && OUT_FILE="reboot-indication.txt" || OUT_FILE="$1" [[ -z "${2}" ]] && IN_FILE="hosts.txt" || IN_FILE="$2" while IFS= read -r host; do indication="$(ssh -n "$host" 'LANG=C who -b' | awk '{print $(NF-1)" "$NF}')" printf '%-14s %s\n' "$host" "$indication" >> "$OUT_FILE" done < "$IN_FILE" < /dev/null/ заменяется на -n команды ssh. Из man ssh: -n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background... This does not work if ssh needs to ask for a password or passphrase; see also the -f option. IFS= read -r line - как говорит Стефан Чазелас в своем энциклопедическом ответе - это канонический способ чтения одной строки ввода с встроенным read. Ключ состоит в том, что read читает слова из строки (возможно, обратной косой черты), где слова ограничены $IFS и обратная косая черта может использоваться для исключения разделителей (или продолжения строк). Поэтому команда read должна быть изменена для чтения строк. IFS= изменяет внутренний разделитель полей на нулевую строку, таким образом, мы сохраняем в результате начальные и конечные пробелы. Опция -r - необработанный вход - отключает интерпретацию обратных слэшей и продолжения строки в прочитанных данных (ссылка). printf '%s %s' "$VAR1" "$VAR2" обеспечит лучший выходной формат (ссылка). LANG=C гарантирует идентичный вывод who -b на каждом сервере, поэтому будет гарантирован синтаксический анализ вывода с awk. Обратите внимание, что предполагается ~/.ssh/config файл и дополнительные параметры, поскольку -p 2222 не нужны (ссылка).

Вызвать этот скрипт ssh-check.sh (не забудьте chmod +x) и использовать его таким образом:

< /dev/null/ заменяется опцией -n команды ssh. Из man ssh: -n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background... This does not work if ssh needs to ask for a password or passphrase; see also the -f option.

< /dev/null/ заменяется опцией -n команды ssh. Из man ssh:

./ssh-check.sh 'my-custom.out' ./ssh-check.sh 'my-custom.out' 'my-custom.in'

Установить пользовательское значение для выходного файла; установить пользовательское значение также для входных файлов:

5
ответ дан 18 July 2018 в 01:22

Наконец, я предполагал, что остальная часть скрипта в порядке. Затем я последовал за комментарием @ dessert и использовал shellcheck, которые привели меня к актуальной проблеме и ее решению:

SC2095: Добавьте < /dev/null, чтобы предотвратить ssh от проглатывания stdin.

Итак, вы должны изменить свой сценарий таким образом:

ssh -p 2222 "$p" 'who -b' < /dev/null | awk '{print $(NF-1)" "$NF}' >> 'file2'

Согласно комментарию @ dessert и спасибо в полезные советы, представленные в комментариях @EliahKagan и shellcheck , полный скрипт может выглядеть так:

#!/bin/bash # Collect the user's input, and if it`s empty set the default values [[ -z "${1}" ]] && OUT_FILE="reboot-indication.txt" || OUT_FILE="$1" [[ -z "${2}" ]] && IN_FILE="hosts.txt" || IN_FILE="$2" while IFS= read -r host; do indication="$(ssh -n "$host" 'LANG=C who -b' | awk '{print $(NF-1)" "$NF}')" printf '%-14s %s\n' "$host" "$indication" >> "$OUT_FILE" done < "$IN_FILE" < /dev/null/ заменяется на -n команды ssh. Из man ssh: -n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background... This does not work if ssh needs to ask for a password or passphrase; see also the -f option. IFS= read -r line - как говорит Стефан Чазелас в своем энциклопедическом ответе - это канонический способ чтения одной строки ввода с встроенным read. Ключ состоит в том, что read читает слова из строки (возможно, обратной косой черты), где слова ограничены $IFS и обратная косая черта может использоваться для исключения разделителей (или продолжения строк). Поэтому команда read должна быть изменена для чтения строк. IFS= изменяет внутренний разделитель полей на нулевую строку, таким образом, мы сохраняем в результате начальные и конечные пробелы. Опция -r - необработанный вход - отключает интерпретацию обратных слэшей и продолжения строки в прочитанных данных (ссылка). printf '%s %s' "$VAR1" "$VAR2" обеспечит лучший выходной формат (ссылка). LANG=C гарантирует идентичный вывод who -b на каждом сервере, поэтому будет гарантирован синтаксический анализ вывода с awk. Обратите внимание, что предполагается ~/.ssh/config файл и дополнительные параметры, поскольку -p 2222 не нужны (ссылка).

Вызвать этот скрипт ssh-check.sh (не забудьте chmod +x) и использовать его таким образом:

< /dev/null/ заменяется опцией -n команды ssh. Из man ssh: -n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background... This does not work if ssh needs to ask for a password or passphrase; see also the -f option.

< /dev/null/ заменяется опцией -n команды ssh. Из man ssh:

./ssh-check.sh 'my-custom.out' ./ssh-check.sh 'my-custom.out' 'my-custom.in'

Установить пользовательское значение для выходного файла; установить пользовательское значение также для входных файлов:

5
ответ дан 24 July 2018 в 17:23

Вы забыли закрыть цикл while-do. Добавьте done в конец.

filename='file1' while read p; do ssh -p 2222 $p 'who -b' | awk '{print $(NF-1)" "$NF}' >> file2* done
5
ответ дан 18 July 2018 в 01:22

Вы забыли закрыть цикл while-do. Добавьте done в конец.

filename='file1' while read p; do ssh -p 2222 $p 'who -b' | awk '{print $(NF-1)" "$NF}' >> file2* done
5
ответ дан 24 July 2018 в 17:23

Другие вопросы по тегам:

Похожие вопросы: