在我自己的python脚本中用作库时,我无法使用Fabric。我做了一个非常简短的例子fabfile.py
来证明我的问题:
#!/usr/bin/env python
from fabric.api import *
print("Hello")
def test():
with settings(host_string='myIp', user="myUser", password="myPassword"):
run("hostname")
if __name__ == '__main__':
test()
正在运行fab
就像魅力一样:
$ fab test
Hello
[myIp] run: hostname
[myIp] out: ThisHost
[myIp] out:
Done.
Disconnecting from myUser@myIp... done.
好的,现在,运行没有fab的python脚本似乎在某个地方破解了:
$ python fabfile.py
Hello
[myIp] run: hostname
它立即返回,所以它似乎甚至没有等待回应。也许有错误,但我不知道如何输出。
我在我的流浪虚拟机中运行此脚本。由于fab
执行没有任何错误,我想这应该不是问题!
更新
脚本似乎崩溃,因为它在第一个run
之后没有执行任何操作。另一方面,local
有效!
我们在同事笔记本电脑上执行了该脚本,它运行没有任何问题。我在Ubuntu 10.04上使用Python 2.6.5和fabric 1.5.1,所以我猜它有一些问题!有没有办法正确调试?
答案 0 :(得分:2)
我遇到过类似的问题,fab命令没有出错而只是第一个run()
/ sudo()
命令上的空行。
所以我把run()
命令放到try:except:block并打印回溯:
def do_something():
print(green("Executing on %(host)s as %(user)s" % env))
try:
run("uname -a")
except:
import traceback
tb = traceback.format_exc()
print(tb)
我看到脚本在第419行的fabfile/network.py
中退出时捕获了EOFError或TypeError。我将脚本修改为:
...
except (EOFError, TypeError) as err:
print err
# Print a newline (in case user was sitting at prompt)
print('')
sys.exit(0)
...
然后打印出来:
connect() got an unexpected keyword argument 'sock'
所以我在上面的几行中删除了connect方法中的sock关键字参数,它就像魅力一样。我想这是一个paramiko
版本的问题,它不允许使用sock关键字。
版本:
Python 2.7.3
Fabric >= 1.5.3
paramiko 1.10.0
答案 1 :(得分:1)
如果查看fab命令,它看起来像这样:
sys.exit(
load_entry_point('Fabric==1.4.3', 'console_scripts', 'fab')()
)
这意味着它在Fabric包中名为entry_points.txt的文件中查找标记为console_scripts的块,并执行其中列出的方法,在本例中为fabric.main:main
当我们看这个方法时,我们看到参数解析,有趣的fabfile导入然后:
if fabfile:
docstring, callables, default = load_fabfile(fabfile)
state.commands.update(callables)
....
for name, args, kwargs, arg_hosts, arg_roles, arg_exclude_hosts in commands_to_run:
execute(
name,
hosts=arg_hosts,
roles=arg_roles,
exclude_hosts=arg_exclude_hosts,
*args, **kwargs
)
通过一些实验我们可以得到类似的东西:
from fabric import state
from fabric.api import *
from fabric.tasks import execute
from fabric.network import disconnect_all
def test():
with settings(host_string='host', user="user", password="password"):
print run("hostname")
if __name__ == '__main__':
state.commands.update({'test': test})
execute("test")
if state.output.status:
print("\nDone.")
disconnect_all()
这显然是非常不完整的,但也许你只需要添加
disconnect_all()
脚本末尾的行