用作库不起作用的结构

时间:2012-12-03 10:29:48

标签: python fabric

在我自己的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,所以我猜它有一些问题!有没有办法正确调试?

2 个答案:

答案 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()
脚本末尾的