当我运行此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,您看到此行为的原因是因为主机列表是在调用task函数之前构造的。因此,即使您要在函数内部更改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开始执行['other_host', ]时,主机列表已经设置为mycmd

10-08 20:00