簡體   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