Expect中被忽视的超时
以前写过一个expect脚本,用于每天凌晨登录远端sftp服务器同步文件,但是偶尔会发现登录失败,查不出来原因,所以设置了每天同步两次,可惜依然有时候失败。直到我发现了expect的超时设置,据说expect默认超时时间是10s。
为了证实这个问题,我写了简易的脚本做验证,把登录sftp换成了http服务,道理是一样的。下面是在没有给expect设置超时的情况,我写了个flask服务,用来做测试,demo.py。
简单的http服务
#!/usr/bin/python
import flask
import time
app = flask.Flask(__name__)
@app.route("/sleep")
def justsleep():
time.sleep(15)
return "awake\n"
if __name__ == '__main__':
app.run()
服务路径是http://localhohst:5000/sleep
,作用是在休息15s之后,给客户端返回awake的字符串。
没有timeout设置的expect
下面是我的expect脚本,http_client.exp
#!/usr/bin/expect -f
spawn /usr/bin/curl -s http://127.0.0.1:5000/sleep
expect
这个脚本的用途是去curl http://127.0.0.1:5000/sleep 服务,等待命令结束。
运行服务和脚本试试,先启动服务:
$ python demp.py
然后运行exp脚本:
$ /usr/bin/expect ./http_client.exp
spawn /usr/bin/curl -s http://127.0.0.1:5000/sleep
等等,过了10s之后,脚本没等到服务返回的awake字样就退出了。而且flask有报错
Exception happened during processing of request
...
也就是说,http_client.exp正在运行着,然后就突然退出了。这个就是就是在expect里不设置超时导致的问题,expect默认超时时间为10s,如果10s中还没有返回,就会退出脚本。
解决超时问题
修改http_client.exp文件,如下
#!/usr/bin/expect -f
set timeout 20
spawn /usr/bin/curl -s http://127.0.0.1:5000/sleep
expect
这次添加了一行set timeout 20
,也就是设置20s的超时时间。再次运行http_client.exp脚本,等待15s,终于看到了awake。
$ ./http_client.exp
spawn /usr/bin/curl -s http://127.0.0.1:5000/sleep
awake
所以,这里的timeout指定了最长的等待时间。
最后
所以回到我遇到的问题上,就是sftp脚本要去同步远程服务器上,由于中间的网络很慢,而expect默认超时时间是10s,如果10s中还未能登录成功,自然就无法同步远程sftp服务器的文件。
如果不想不能确定要设置多长的超时时间,可以尝试set timeout -1
,也就是永不超时。祝你玩得愉快。
当前暂无评论 »