我正在使用Python 3.6和Fabric 2.4。我正在使用Fabric将SSH连接到服务器并运行一些命令。我需要为远程服务器上运行的命令设置环境变量。文档表明这样的事情应该有效:
from fabric import task
@task(hosts=["servername"])
def do_things(c):
c.run("command_to_execute", env={"KEY": "VALUE"})
但这不起作用。这样的事也应该是可能的:
from fabric import task
@task(hosts=["servername"])
def do_things(c):
c.config.run.env = {"KEY": "VALUE"}
c.run("command_to_execute")
但这也不起作用。我觉得我错过了什么。有人可以帮忙吗?
根据that part of the official doc,connect_kwargs
对象的Connection
属性旨在取代env
dict。我用它,它按预期工作。
正如Fabric网站所述:
造成这种情况的根本原因通常是因为SSH服务器通过非常有限的shell调用运行非交互式命令:/ path / to / shell -c“command”(例如,OpenSSH)。当以这种方式运行时,大多数shell不被认为是交互式shell或登录shell;然后这会影响加载哪些启动文件。
你在这个页面上阅读更多内容link
因此,您尝试执行的操作无效,解决方案是传递您要显式设置的环境变量:
from fabric import task
@task(hosts=["servername"])
def do_things(c):
c.config.run.env = {"KEY": "VALUE"}
c.run('echo export %s >> ~/.bashrc ' % 'ENV_VAR=VALUE' )
c.run('source ~/.bashrc' )
c.run('echo $ENV_VAR') # to verify if it's set or not!
c.run("command_to_execute")
你可以尝试:
@task
def qa(ctx):
ctx.config.run.env['counter'] = 22
ctx.config.run.env['conn'] = Connection('qa_host')
@task
def sign(ctx):
print(ctx.config.run.env['counter'])
conn = ctx.config.run.env['conn']
conn.run('touch mike_was_here.txt')
并运行:
fab2 qa sign
创建Connection
对象时,请尝试添加inline_ssh_env=True
。
是否将“inline”环境变量作为前缀发送到命令字符串(
export VARNAME=value && mycommand here
)前面,而不是尝试通过SSH协议本身提交它们(这是默认行为)。如果远程服务器具有受限制的AcceptEnv
设置(这是常见的默认设置),则这是必需的。