在Fabric中,如何从另一个Python文件执行任务?

6 投票
2 回答
3562 浏览
提问于 2025-04-18 06:16

我有一个叫做fabfile.py的文件,里面定义了一些任务:

# fabfile.py
from fabric.api import *

@task
def start():
  # code

@task
def stop():
  # code

然后,当我尝试用fabric的execute函数来调用这些任务时,像这样:

# main.py
from fabric.api import execute
from fabfile import * # I don't really know if this is necessary 
                      # or how should it be done
def main():
  execute('start')

就会出现这个错误:

Fatal error: None is not callable or a valid task name

我的目的是想做一个包装器,可以用不同的参数来调用fabfile里面的一些任务。也就是说,当我调用这个主程序时,执行的任务名称是从参数中获取的,所以我不能直接调用函数,而是要用任务的名字。

这样该怎么做呢?也许我对fabric的工作方式理解错了?

谢谢

2 个回答

1

其实我们不一定要用fabfile.py这个名字。我们可以给fabfile起任何名字。只需要在使用的时候加一个参数--fabfile就可以了。

Syntax:
fab --fabfile=<Your File Goes Here> function_name

Example:
fab --fabfile=test test_deploy
8

execute('start') 改成 execute(start)

我不知道为什么传一个任务名称给 execute 不管用,但有个解决办法:

import fabfile
execute(getattr(fabfile, 'start'))

更新: 看了一些代码并测试了一下 fabric,我觉得 execute('task_name') 只能在 fabric 任务加载后使用。默认情况下,你可以在 fabfile.py 里这样用:

@task
def task1():
    #do task1

@task
def task2():
    #do task2

@task
def task3():
    #do task1 and task2
    execute('task1')
    execute('task2')

然后你可以用 fab task3 来一起执行 task1task2。不过到现在为止,我还是在用 fabric 这个工具。

再更新 :-)

然后我看了一些 fabric 的代码,发现使用 fabric 作为工具会调用 fabric.main.main,这个会调用 fabric.main.load_fabfile 来加载 fabfile 中的任务。

因为你是用 python main.py 来运行你的脚本,即使你导入了 fabfile,fab 任务也不会被加载。所以我在你的 main.py 里加了一些代码:

docstring, callables, default = load_fabfile('fabfile.py')
state.commands.update(callables)

现在,execute('start') 就能像你想的那样正常工作了。

撰写回答