我的目标是使用expect重命名sftp服务器上的文件,如果重命名失败,则退出expect返回状态代码1
我的期望脚本工作正常 - 它成功重命名。
如果重命名失败,我无法弄清楚如何退出并显示状态代码。
ubuntu@ip-10-0-0-138:~$> cat expect_script.txt
spawn sftp -o "StrictHostKeyChecking no" [email protected]
expect "password:"
send "somesupersecretpassword\n"
expect "sftp>"
send "rename /var/www/static/tmp-93121715.mp4 /var/www/static/91329728.mp4\n"
expect "sftp>"
send "rename /var/www/static/91329728.mp4 /var/www/static/tmp-93121715.mp4\n"
expect "sftp>"
send "bye\n"
expect "#"
exit
这是我运行脚本时的输出:
ubuntu@ip-10-0-0-138:~$> expect -f expect_script.txt
spawn sftp -o StrictHostKeyChecking no [email protected]
[email protected]'s password:
Connected to nginx.localvpc.
sftp> rename /var/www/static/tmp-93121715.mp4 /var/www/static/91329728.mp4
rename /var/www/static/tmp-93121715.mp4 /var/www/static/91329728.mp4
sftp> rename /var/www/static/91329728.mp4 /var/www/static/tmp-93121715.mp4
rename /var/www/static/91329728.mp4 /var/www/static/tmp-93121715.mp4
sftp> bye
bye
ubuntu@ip-10-0-0-138:~$>
如果重命名失败,任何人都可以建议我可以做什么以返回代码零退出吗?
附加问题...在我的期望脚本结束时退出的正确方法是什么?它是其中之一吗?
exit
close
expect eof
谢谢!
答案1
您需要通过匹配该文本并对其进行操作来检查重命名失败。这可以抽象为proc
(TCL 称之为子例程或函数)。
spawn ...
set ret 0
expect "sftp>"
proc sftp_rename {from to} {
global ret
send "rename $from $to\n"
expect {
-ex "Couldn't" { set ret 42; exp_continue }
"sftp>"
}
}
sftp_rename /var/www/static/tmp-93121715.mp4 /var/www/static/91329728.mp4
sftp_rename /var/www/static/91329728.mp4 /var/www/static/tmp-93121715.mp4
send "bye\n"
expect eof
exit $ret
我会使用,expect eof
因为我预计sftp
连接会在那时消失。
答案2
我的手册页expect
说:
exit [-opts] [status]
[...] status(如果未指定则为 0)作为 Expect 的退出状态返回。
所以你只是想要exit 1
。
至于您的三种选择,expect eof
将等待命令expect
正在与之通信以达到 EOF。expect
之后您可以继续该脚本。expect eof
在这只是选项之一的情况下,或者当遥控器可能检测到断开连接并将其视为错误时,非常有用。 (当然,如果谈话双方都等待对方停止,那么他们就会陷入困境。)
close
将关闭与其他进程的连接,因此在某种意义上与expect eof
.同样,您的脚本在此之后可以继续。close
在退出脚本之前使用并没有多大作用,因为exit
也隐式地使用了 will close
。
然后退出exit
你的脚本。三者之间的选择取决于您想要做什么。如果你想退出,我会说 just exit
,然后让远程处理 EOF。