期望脚本获取多个服务器的输出

期望脚本获取多个服务器的输出

我正在尝试从多个服务器获取 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

可靠的文档您可以找到有关如何规则服务器的信息。

相关内容