다음과 같은 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에는 1000개의 유사한 항목이 포함되어 있습니다. 나는 다음을 시도하고 있습니다. 60999,J0777...은 명령을 실행하는 데 필요한 엔터티입니다.
그래서 각 줄을 읽고 분할하여 해당 엔터티에 해당하는 DIF 번호가 무엇인지 확인하려고 합니다.
예를 들어 DIF2를 읽으면 호스트 이름 2에 ssh를 연결하고 명령을 실행하여 60999의 데이터를 가져와야 함을 의미합니다.
DIF3을 읽으면 엔터티 J0777이 호스트 이름 3에서만 실행될 수 있음을 의미합니다.
답변1
해설자: 귀하의 (예?) cat
과 ( awk
는) 쓸모가 없으므로 반복하고 테스트할 필요가 없습니다 echo|cut
.
원격 sudo의 비밀번호를 입력해야 함을 명확히 한 후둘 다ssh
터미널을 이용하여 입력하고 -t
입력이 PTY로 전달되도록 지정해 보겠습니다 . 이건 기본적으로 사기야SSH로 인해 while 루프가 중지됩니다.동일한 증상이 나타나지 않더라도.
방법 1: 루프에 대한 stdin을 리디렉션(또는 파이프)하되 리디렉션합니다.뒤쪽에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에서는 그렇게 한다고 하지만 이렇게 하지 않습니다). 처음에 실제로 하나의 필드만 사용하는 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