[英]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.