2

我有一个包含 IP 地址、文件位置和密码的文件。我不能使用 ssh 密钥身份验证,这就是为什么我只能在 bash 脚本中使用期望。该文件包含以下信息,以空格分隔:

ip位置密码

ip位置密码

ETC

我的脚本是:

 VAR=$(expect -c "
        set fid [open "file.conf" w]
        set content [read $fid]
        close $fid
        set records [split $content "\n"]
        foreach rec $records {
        set fields [split $rec]
        lassign $fields\ ip location password
        puts "$ip"
        puts "$location"
        puts "$password"}
        spawn ssh $ip tail -f $location > /home/log_$ip 2>/dev/null &
        expect {
                ".*Are.*.*yes.*no.*" { send "yes\n" }
                "*?assword:*" { send "$password\r" }
           }
    ")

回声“$VAR”

当我运行脚本时,它给了我这个错误:

错误 #args: 应该是“读取 channelId ?numChars?” 或“读取?-nonewline?channelId”,同时执行从“set content [read]”中调用的“read”

4

1 回答 1

1

您需要将期望主体括在单引号中,因此在期望开始执行之前,shell 不会扩展期望变量。

此外,如果您点击“是...是...否”提示,那么您需要使用exp_continue,这样您就可以继续期待密码提示。

不要用“w”打开配置文件——你会破坏文件内容。你正在阅读它,所以打开它阅读

VAR=$(expect -c '
    set fid [open "file.conf" r]
    while {[gets $fid line] != -1} {
        lassign [split $line] ip location password
        puts "$ip"
        puts "$location"
        puts "$password"
        spawn ssh $ip tail -n 20 $location > /home/log_$ip 2>/dev/null &
        expect {
            -re "Are.*yes.*no" { send "yes\r"; exp_continue }
            -gl "*?assword:*" { send "$password\r" }
        }
    }
')

我不确定当您重定向 spawn 输出时这是否会起作用:我担心 expect 将无法使用。如果这不起作用,请删除“ > /home/log_$ip 2>/dev/null &”或使用

spawn ssh $ip tail -n 20 $location 2>/dev/null | tee /home/log_$ip

对于背景,您可能必须做这样的事情(未经测试)

expect -c '...' > /home/log_$ip 2>&1 &
expect_pid=$!

# ...

# later
wait $expect_pid
VAR=$(< /home/log_$ip)
do something with "$VAR"
于 2013-10-24T16:03:39.370 回答