我正在一个需要一些帮助的项目上。
我已经完成了完成该项目所需的大多数信息,但是唯一的滞后就是在远程计算机上运行本地Shell脚本。 我们知道,使用“ expect”库的脚本无法识别Linux命令。 这里我们尝试了两个用例:
1)仅使用一个期望脚本在远程服务器上运行所需的命令列表,该脚本既具有脚本执行功能,又具有使用scp将输出推送到本地计算机的功能,这是此代码的片段:
`chmod 777 localscript.sh
cat > script1.sh <<- "ALL"`
`#!/usr/bin/expect
set password [lindex $argv 0];
set ipaddress [lindex $argv 1];
set timevalue [lindex $argv 2];
set timeout $timevalue
spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
expect "assword:"
send "$password\r"
set timeout $timevalue
spawn /usr/bin/scp username@$2:"/path/from/source/*" /path/to/destination/folder/
expect "assword:"
send "$password\r"
interact
ALL
chmod 777 script1.sh
./script1.sh $password $2 $timevalue`
2)在单独的Expect脚本中在远程服务器上运行所需的命令列表,并使用scp获取其他脚本中的文件:
`cat > script1.sh <<- "ALL" `
`#!/usr/bin/expect
set password [lindex $argv 0];
set ipaddress [lindex $argv 1];
set timevalue [lindex $argv 2];
set timeout $timevalue
spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
expect "assword:"
send "$password\r"
interact
ALL
cat > script2.sh <<- "ALL2"`
`#!/usr/bin/expect
set password [lindex $argv 0];
set ipaddress [lindex $argv 1];
set timevalue [lindex $argv 2];
set timeout $timevalue
spawn /usr/bin/scp username@ipaddress:"/path/from/source/*" /path/to/destination/folder/
expect "assword:"
send "$password\r"
interact
ALL2
chmod 777 localscript.sh script1.sh script2.sh
./script1.sh $password $2 $timevalue
sleep 5
./script2.sh $password $2 $timevalue`
我认为以上代码在各自方面都应该有效,但是,相同的输出似乎是出乎意料的:
1)输入密码后,几乎同时执行ssh和scp命令,因此它没有给本地脚本足够的时间来完成其工作,这是我看到的输出:
spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh
Warning private system unauthorized users will be prosecuted.
username@1.2.3.4's password: spawn /usr/bin/scp
username@1.2.3.4:"/home/some/file/*" /another/file/
Warning private system unauthorized users will be prosecuted.
username@1.2.3.4's password:
scp: /home/some/file/*: No such file or directory
请注意:在没有期望的情况下,此功能可以正常工作
2)在这里,我们分别执行ssh和scp,但是似乎无法识别文件localscript.sh存在:
spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh
Warning private system unauthorized users will be prosecuted.
username@1.2.3.4's password:
bash: localscript.sh: No such file or directory
Warning private system unauthorized users will be prosecuted.
username@1.2.3.4's password:
scp: /home/some/file/*: No such file or directory
任何有关此问题的反馈将不胜感激,我认为第一种方法可能是一种可行的解决方案,除了以下事实:生成速度太快并且“ sleep”或“ after”命令均无用/起作用。我认为第二种方法也是有效的,但是在远程服务器上运行本地脚本的方式似乎与使用“期望”时在Linux上的常规方式不同。
很抱歉,我希望尽快摆脱苦难:)
答案 0 :(得分:0)
确实是您设置的超时在期望时不起作用。生成两个脚本,每次生成后的expect "assword:"
实际上是在捕获并响应相同的密码提示。
expect
实际上比凭空浏览会使您相信的更为复杂。每个spawn
应该返回一个PID,您可以将其与expect
一起使用,以查找特定进程的输出。
expect
也可以分为多个部分,并且可以定义子例程。这是一些更高级的使用示例https://wiki.tcl-lang.org/10045
在这种情况下,我建议等待scp
完成之后再生成下一个进程。
expect {
"assword:" {
send "$password\r"
exp_continue # Keep expecting
}
eof {
puts -nonewline "$expect_out(buffer)"
# eof so the process should be done
# It is safe to execute the next spawn
# without exp_continue this expect will
# break and continue to the next line
}
}