не может удаленно выполнить команду с помощью ssh over for loop

Я пытаюсь запустить цикл 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.

0
23.07.2017, 06:35
1 ответ

В сторону :вашего (примера?)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
1
28.01.2020, 02:45

Теги

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