期待ssh无密码

时间:2013-10-24 15:18:26

标签: bash ssh expect

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

ip location password

ip location password

我的脚本是:

 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"     执行时 "阅读"     从内部调用 "设置内容[read]"

1 个答案:

答案 0 :(得分:1)

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

此外,如果您点击“are ... yes ... no”提示,那么您需要使用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输出时这是否会起作用:我担心期望没有任何效果。如果这不起作用,请删除“> /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"