我正在尝试从多个服务器获取 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
在可靠的文档您可以找到有关如何规则服务器的信息。