期望在 bash 脚本中

Expect within bash script

我正在尝试将 expect 脚本实现到 bash 脚本中。请耐心等待,因为我是 bash/expect.

的新手

这是按预期工作的期望脚本:

log_user 0

file delete foo.txt

set fh [open foo.txt a]

set servers {xxx@server1 xxx@server2}

foreach s $servers {
spawn ssh $s
expect "password: "
send "PASSWORD\r"
expect "$ "
send "grep "something" /some/log/file.log"
expect "$ " { puts $fh "$expect_out(buffer)"}
send "exit\r"
}

close $fh

现在,我希望将此 expect 脚本包含在 bash 脚本中,但它没有按预期工作。

这是我目前的情况:

#!/bin/bash

XYZ=$(expect -c "
file delete foo.txt

set fh [open foo.txt a]

set servers {xxx@server1 xxx@server2}

foreach s $servers {
spawn ssh $s
expect "password: "
send "PASSWORD\r"
expect "$ "
send "grep "something" /some/log/file.log"
expect "$ " { puts $fh "$expect_out(buffer)"}
send "exit\r"
}

close $fh
")

echo "$XYZ"

我得到的错误是:

command substitution: line 42: syntax error near unexpected token `('
command substitution: line 42: `expect "$ " { puts $fh "$expect_out(buffer)"}'

我愿意接受任何其他方式来实现它! :)

您可以使用 /usr/bin/expect -c 来执行 expect 命令:

#!/bin/bash

/usr/bin/expect -c ' 

file delete foo.txt

set fh [open foo.txt a]

set servers {xxx@server1 xxx@server2}

foreach s $servers {
spawn ssh $s
expect "password: "
send "PASSWORD\r"
expect "$ "
send "grep "something" /some/log/file.log"
expect "$ " { puts $fh "$expect_out(buffer)"}
send "exit\r"
}

close $fh
'

Bertrand 的回答是解决您问题的一种方法,但没有解释您所做的问题。

Bash 尝试在双引号字符串中扩展变量,因此您的 expect 脚本将在您希望看到 $servers$s$fh。此外,您有 triply-nested 组 double-quoted 字符串,这将导致解析 expect.

的参数时出现各种问题

这是一个见仁见智的问题,但我认为当某些东西达到它被认为是一个独立程序的特定点时,它应该被分离到一个单独的文件中。

#!/usr/bin/expect
log_user 0

file delete foo.txt

set fh [open foo.txt a]

set servers {xxx@server1 xxx@server2}

foreach s $servers {
    spawn ssh $s
    expect "password: "
    send "PASSWORD\r"
    expect "$ "
    send "grep 'something' /some/log/file.log"
    expect "$ " {
        puts $fh "$expect_out(buffer)"
    }
    send "exit\r"
}

close $fh

确保它是可执行的,然后从您的 bash 脚本中调用它:

#!/bin/bash
/usr/local/bin/my_expect_script

(要真正正确地做到这一点,您应该设置 public 密钥身份验证,然后您可以通过 运行 ssh server "grep 'something' /some/log/file.log" 直接从 bash 完全摆脱期望)