如何在我的Python Fabric`fabfile.py`中的函数中正确设置`env.hosts`?

时间:2012-01-31 06:30:20

标签: python deployment fabric

当我运行此fabfile.py ...

from fabric.api import env, run, local, cd

def setenv(foo):
  env.hosts = ['myhost']

def mycmd(foo):
  setenv(foo)
  print(env.hosts)
  run('ls')

使用此命令fab mycmd:bar。我得到了这个输出......

['myhost']
No hosts found. Please specify (single) host string for connection:

什么,什么?!我不明白吗?我设置了env.hosts,它似乎在mycmd函数内部有效,但由于某种原因,run命令不知道hosts我已经明确指出。

让我感到困惑。任何帮助将不胜感激!

5 个答案:

答案 0 :(得分:7)

@Chris,你看到这种行为的原因是因为在调用任务函数之前构造了主机列表。所以,即使你在函数内部改变env.hosts,它也不会产生任何影响。

而命令fab setenv:foo mycmd:bar会产生你期望的东西:

$ fab setenv:foo mycmd:bar
[myhost] Executing task 'mycmd'
['myhost']
[myhost] run: ls

这与接受的答案相同,但由于setenv的定义方式,需要一个参数。

另一个例子:

from fabric.api import env, run, local, cd

env.hosts = ['other_host']

def setenv(foo):
    env.hosts = ['myhost']

def mycmd(foo):
    setenv(foo)
    print('env.hosts inside mycmd: %s' % env.hosts)
    run('ls')

这个输出是:

$ fab mycmd:bar
[other_host] Executing task 'mycmd'
env.hosts inside mycmd: ['myhost']
[other_host] run: ls

Fatal error: Name lookup failed for other_host

Underlying exception:
    (8, 'nodename nor servname provided, or not known')
Aborting.

如您所见,当结构开始执行['other_host', ]时,主机列表已设置为mycmd

答案 1 :(得分:5)

你这样做的方式通常不是我如何使用Fabric。

from fabric.api import *

def hostname():

    env.hosts = ['myhosts']

def mycmd():
    print env.hosts
    run('ls -l')

为了运行这个,我会做

fab hostname mycmd

这允许您分别在哪个主机/主机上执行命令。

希望它有所帮助。

答案 2 :(得分:3)

您是否尝试使用hosts装饰器?

from fabric.api import env, run, hosts

@hosts('myhost')
def mycmd(foo):
    print(env.hosts)
    run('ls')

答案 3 :(得分:1)

我知道这个问题太老了,但是以防万一有人偶然发现了这个问题,我发现您并不需要将其本身称为fab文件(您的文件不需要称为“ fabfile” “ .py”和命令不必是client = commands.Bot(command_prefix="..") illegal_words = ["apple", "pear", "banana"] @client.event async def on_message(ctx): [word in message.content for word in illegal_words] any([word in message.content for word in illegal_words]) await ctx.channel.purge(limit=1) await ctx.send("""That Word Is Not Allowed To Be Used! Continued Use Of Mentioned Word Would Lead To Punishment!""") 。由于您正在导入所需的fab元素,因此您可以调用任何您想要的文件(我们称其为“ testfile.py”),只需使用execute函数在文件中。这将使您的命令fab setenv(foo) mycmd(bar)

在测试文件中,像往常一样设置所有内容,但是使用python testfile.py关键字启动功能。您的文件如下所示:

execute

**需要特别注意的是,execute命令看上去确实像常规函数调用。它将调用该函数并以逗号分隔的一行发送参数。您可以找到更多信息here

因此,您将启动程序,该程序将首先调用setenv,然后setenv将执行 mycmd函数。这样,您还可以在同一阵列中设置多个主机。像这样:

from fabric.api import env, run

def setenv(foo):
    env.hosts = ['myhost']
    execute(mycmd, bar)

def mycmd(bar):
    run('ls')

setenv(foo)

答案 4 :(得分:0)

我已经想出了如何让它发挥作用:

from fabric.api import env, run, local, cd

def setenv(foo):
  env.hosts = ['myhost']
  return env

def mycmd(foo):
  env = setenv(foo)
  print(env.hosts)
  run('ls')