3

在我自己的 python 脚本中用作库时,我无法让织物工作。我做了一个非常简短的例子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,所以我猜这其中有一些问题!有什么办法可以正确调试吗?

4

2 回答 2

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)

我看到脚本在fabfile/network.py捕获 EOFError 或 TypeError 时在第 419 行退出。我将脚本修改为:

...
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
于 2013-03-08T14:04:55.430 回答
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()

脚本末尾的行

于 2012-12-03T22:57:52.807 回答