Я пытаюсь запустить цикл for, который выглядит примерно так
cat all_data |
awk '{print $1 " "$2" " $3}' |
while read inst type serial ; do
echo $inst
if [ `echo ${inst} | cut -d '-' -f2` = H3 ]; then
ssh -t username@hostname3 "sudo ls"
elif [ `echo ${inst} | cut -d '-' -f2` = H2 ] ; then
ssh -t username@hostname2 "sudo ls"
elif [ `echo ${inst} | cut -d '-' -f2` = H1 ]; then
ssh -t username@hostname1 "sudo ls"
fi
done
Я не могу запустить часть ssh -t, он говорит, что псевдотерминал не будет выделен, потому что stdin не является терминалом sudo: нет tty и не указана программа askpass Я пробовал с -t -t и -n, не повезло. Я не могу редактировать файл visudo с хоста, с которого я выполняю эту команду.
$ cat all_data
ABC-DIF2 DELL-800 60999
ABC-DIF3 HP-DL340 J0777
ABC-DIF4 DELL-800 P0087
.
.
.
all_data содержит тысячи похожих записей. Что я пытаюсь сделать следующим образом. 60999, J0777 ... - это объекты, на которых мне нужно запускать команды.
Итак, я пытаюсь прочитать каждую строку, разделить и проверить, какой номер DIF соответствует объекту.
например, если я читаю DIF2, это означает, что мне нужно ssh в hostname2 и запустить команду для получения данных на 60999
Если я читаю DIF3, это означает, что объект J0777 может быть запущен только с hostname3.
В сторону :вашего (примера?)cat
и awk
бесполезны, и вам не нужны повторные echo|cut
и тесты.
После разъяснения того, что вам нужно ввести пароль (s )для удаленного sudo, вам нужно оба позволить ssh
использовать ввод терминала и указать -t
, чтобы он пересылал этот ввод как PTY. Это в основном обман SSH вызывает остановку цикла while , хотя вы не достигли того же симптома.
Метод 1 :перенаправить (или передать )стандартный ввод для цикла, но перенаправить его назад для ssh
while read inst type serial; do
case ${inst#*-} in
(DIF1) ssh </dev/tty -t user@host1 "sudo blah";;
(DIF2) ssh </dev/tty -t user@host2 "sudo blech";;
# more as needed
esac
done <alldata
# or cat/awk/whatever | while read... done
Метод 2 :использовать другой блок -номер (не стандартный )для всех данных
while read <&3 inst type serial; do
case ${inst#*-} in
(DIF1) ssh -t user@host1 "sudo blah";;
(DIF2) ssh -t user@host2 "sudo blech";;
# more
esac
done 3<alldata
# or while read... done 3< <(cat/awk/whatever) with zsh/bash
Метод 3 заключается в использовании for
цикла (, которого вы не использовали, хотя в вашем вопросе сказано, что вы )читали его аргументы без какого-либо канала.Для вашего исходного Q, который на самом деле использовал только одно поле, это легко:
IFS='
' # split on newline only
set -o noglob # disable globbing
for inst in $(awk '{print $1}' alldata); do
# as for method 2
done
но ваше редактирование говорит, что вы хотите использовать хотя бы одно другое поле, поэтому вам нужно что-то более уродливое, например:
IFS='
' # split on newline only
set -o noglob # disable globbing
for line in $(awk '{print $1":"$2":"$3}' alldata); do
IFS=:; set -- $line; inst=$1; serial=$3;
# as before
done