繁体   English   中英

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

[英]How can I properly set the `env.hosts` in a function in my Python Fabric `fabfile.py`?

当我运行这个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

颜色让我困惑。 任何帮助,将不胜感激!

@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.

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

您这样做的方式通常不是我使用 Fabric 的方式。

from fabric.api import *

def hostname():

    env.hosts = ['myhosts']

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

要运行它,我会这样做

fab hostname mycmd

这允许您将要执行命令的主机分开。

希望能帮助到你。

您是否尝试过使用主机装饰器?

from fabric.api import env, run, hosts

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

我知道这个问题非常古老,但以防万一有人偶然发现这个问题,我发现您不需要将其称为 fab 文件本身(您的文件不需要称为“fabfile.py”并且命令不需要是fab setenv(foo) mycmd(bar) 。由于您正在导入所需的 fab 元素,因此您可以随意调用该文件(我们称其为“testfile.py”),然后只需使用 execute文件中的函数。这将使您的命令python testfile.py

在测试文件中,像往常一样设置所有内容,但使用execute关键字启动该函数。 您的文件将如下所示:

from fabric.api import env, run

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

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

setenv(foo)

** 需要注意的是,execute 命令确实看起来像一个普通的函数调用。 它将调用该函数并在单个逗号分隔行中发送参数。 你可以在这里找到更多信息

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

env.hosts=['myhost1','myhost2','myhost3']

我已经想出了如何使它工作:

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')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM