여러 서버에서 IQN의 출력을 얻으려고 합니다. 다음 오류가 발생합니다.
오류 출력
spawn /usr/bin/ssh VM2 | /usr/bin/cat /etc/iscsi/initiatorname.iscsi
root@VM2's password:
bash: -c: line 0: syntax error near unexpected token `|'
bash: -c: line 0: `| /usr/bin/cat /etc/iscsi/initiatorname.iscsi'
스크립트
#!/bin/bash
HOSTS="VM2 VM3 VM4 VM1"
read -p "Password: " PASSWORD
for HOST in $HOSTS
do
expect -c "
spawn cat /etc/iscsi/initiatorname.iscsi
expect {
"*password:*" { send $PASSWORD\r;interact }
}
exit
"
done
내가 뭐 잘못 했어요?
답변1
우선, 나는 당신이 달성하고 싶은 것이 무엇인지 잘 이해하지 못합니다.
제가 이해한 바로는 모든 서버에서 이를 원한다는 것입니다 cat /etc/iscsi/initiatorname.iscsi
. 그렇죠?
interact
그런데 왜 모든 서버에서 이 작업을 수행 해야 합니까 ?
각 서버와 파일에 로그인하는 첫 번째 문제에 대한 해결 방법을 게시하겠습니다 cat
. 솔루션도 추가하고 싶으시면 interact
제가 솔루션을 편집해 드릴 수 있습니다 .
expect
그래서 먼저 bash
.
따라서 프로그램을 실행하는 데 사용되는 bash 스크립트는 다음과 같습니다. 이 스크립트는 비밀번호가 인쇄되거나 표시되지 않도록 비밀번호를 묻는 메시지를 표시합니다(직접 수행하기 쉽지 않음 expect
) .
#!/bin/bash
expect_script="./connect_to_many_hosts_and_cat_files.exp"
[ ! -f $expect_script ] && echo expect_script does not exist && exit 1
echo "Please enter a password:"
read -s password
$expect_script $password
이제 expect
스크립트 자체
#!/usr/bin/expect
if {$argc != 1} {
puts "please run expect script using bash script"
puts "that prompts for password"
exit
}
set password [lindex $argv 0]
# replace hosts names with your host names !!!
set hosts "host1 host2"
foreach host [ split $hosts " " ] {
set number_of_password_prompts($host) 0
puts "# "
puts "# ssh $host"
puts "# "
spawn ssh $host
expect {
# here I put password check, just in case password is wrong
# look a bit ugly, but better than nothing
"Password:" {
if { $number_of_password_prompts($host) == 0 } {
incr number_of_password_prompts($host)
puts "# "
puts "# Authenticating try $number_of_password_prompts($host)"
puts "# "
send "$password\r"
exp_continue
} else {
puts "# "
puts "# Password is wrong"
puts "# "
exit
}
}
# in case on host /bin/sh or /bin/bash
"$ " {
puts "# "
puts "# cat /etc/iscsi/initiatorname.iscsi"
puts "# "
send "cat /etc/iscsi/initiatorname.iscsi \r"
expect "$ "
}
# in case on host /bin/csh
"% " {
puts "# "
puts "# cat /etc/iscsi/initiatorname.iscsi"
puts "# "
send "cat /etc/iscsi/initiatorname.iscsi \r"
expect "% "
}
send "exit\r"
expect eof
close
}
}
마지막으로 chmod +x
두 파일을 보호하세요. 다른 방법으로도 Expect를 실행할 수 있습니다. 또한 의도한 위치를 올바르게 배치했는지 확인하세요. 나로서는 그렇습니다 /usr/bin/expect
. 왜냐하면 당신은 다른 사람이 될 수 있기 때문입니다.
중요한 것이 하나 더 있습니다. expect
서버의 프롬프트가 중요하기 때문입니다 . 그렇다면 /bin/bash
조건을 추가했습니다. $
그렇다면 /bin/csh
조건을 추가해야 합니다 %
.
$PS1
귀하의 팁이나 기타 팁이 어떻게 관리되는지 확인하는 것이 매우 중요합니다 ssh
. 프롬프트가 다음과 같은 경우 위 스크립트는 작동하지 않습니다.
user@host:~>
이것이 작동하려면 조건을 추가해야 합니다.expect
"> " {
puts "# "
puts "# cat /etc/iscsi/initiatorname.iscsi"
puts "# "
send "cat /etc/iscsi/initiatorname.iscsi \r"
expect "> "
}
저는 왜 일이 제대로 되지 않는지 알아내려고 여러 날을 보냈습니다.
답변2
이런 경우에는 ansible을 사용하세요.
yum install ansible -y
vim /etc/ansible/hosts
[servers]
192.168.0.2
192.168.0.3
ssh-keygen
공개 키를 대상 서버에 복사합니다. 그런 다음 서버에 연결해 보십시오.
ansible servers -m ping
존재하다신뢰할 수 있는 문서서버를 지배하는 방법에 대한 정보를 찾을 수 있습니다.