Так что я мало знаю о bash и нуждаюсь в некоторой помощи. Я пытаюсь запустить скрипт, подобный этому:
filename='file1'
while read p; do
ssh -p 2222 $p 'who -b' | awk '{print $(NF-1)" "$NF}' >> file2*
то, что я пытаюсь сделать, - это сценарий, который проходит через все адреса в файле1, чтобы увидеть, когда они в последний раз перезагружаются, а затем ответ в файле2 ,
Проблема в том, что он проходит только по первому адресу, а не по другому.
Первый адрес получил пароль, который мне нужно ввести, чтобы продолжить процесс. Может быть, это проблема или я указываю каждую строку в файле1, или я вообще не ошибаюсь?
Наконец, я предполагал, что остальная часть скрипта в порядке. Затем я последовал за комментарием @ 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/ заменяется на [ f9] команды 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'
Установить пользовательское значение для выходного файла; установить пользовательское значение также для входных файлов:
Наконец, я предполагал, что остальная часть скрипта в порядке. Затем я последовал за комментарием @ 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'
Установить пользовательское значение для выходного файла; установить пользовательское значение также для входных файлов:
Наконец, я предполагал, что остальная часть скрипта в порядке. Затем я последовал за комментарием @ 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'
Установить пользовательское значение для выходного файла; установить пользовательское значение также для входных файлов:
Вы забыли закрыть цикл while-do. Добавьте done в конец.
filename='file1'
while read p; do
ssh -p 2222 $p 'who -b' | awk '{print $(NF-1)" "$NF}' >> file2*
done
Вы забыли закрыть цикл while-do. Добавьте done в конец.
filename='file1'
while read p; do
ssh -p 2222 $p 'who -b' | awk '{print $(NF-1)" "$NF}' >> file2*
done
Вы забыли закрыть цикл while-do. Добавьте done в конец.
filename='file1'
while read p; do
ssh -p 2222 $p 'who -b' | awk '{print $(NF-1)" "$NF}' >> file2*
done