我有一个文件,其中包含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]"
答案 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"