我正在修改调用进程的环境并附加到它的PATH以及设置一些新的环境变量。但是,当我在子进程中打印os.environ时,这些更改不会反映出来。知道可能发生了什么吗?
我对实例上的脚本的调用:
ssh_hook = SSHHook(conn_id=ssh_conn_id)
temp_env = os.environ.copy()
temp_env["PATH"] = "/somepath:"+temp_env["PATH"]
run = SSHExecuteOperator(
bash_command="python main.py",
env=temp_env,
ssh_hook=ssh_hook,
task_id="run",
dag=dag)
答案 0 :(得分:3)
如果您查看Airflow SSHHook
class的来源,您会发现它没有将env
参数合并到远程运行所有的命令中。 SSHExecuteOperator
implementation将env=
传递给Popen()
电话号码,但只会将其传递给本地subprocess.Popen()
实施,不远程操作。
因此,简而言之:Airflow不支持通过SSH传递环境变量。如果要获得这样的支持,则需要将它们合并到远程执行的命令中,或者将SendEnv
选项添加到本地执行的ssh命令中以便发送每个命令(即使这样也是如此)仅当远程sshd配置为AcceptEnv
将要接收的特定环境变量名称列入白名单时才有效。
from pipes import quote # in Python 3, make this "from shlex import quote"
def with_prefix_from_env(env_dict, command=None):
result = 'set -a; '
for (k,v) in env_dict.items():
result += '%s=%s; ' % (quote(k), quote(v))
if command:
result += command
return result
SSHExecuteOperator(bash_command=prefix_from_env(temp_env, "python main.py"),
ssh_hook=ssh_hook, task_id="run", dag=dag)
如果您的环境变量是敏感的,并且您不希望使用该命令记录它们,则可以在带外传输它们并获取包含它们的远程文件。
from pipes import quote
def with_env_from_remote_file(filename, command):
return "set -a; . %s; %s" % (quote(filename), command)
SSHExecuteOperator(bash_command=with_env_from_remote_file(envfile, "python main.py"),
ssh_hook=ssh_hook, task_id="run", dag=dag)
请注意,set -a
指示shell导出所有已定义的变量,因此正在执行的文件只需要定义具有key=val
声明的变量;它们会自动导出。如果从Python脚本生成此文件,请确保使用pipes.quote()
引用键和值,以确保它仅执行分配而不运行其他命令。 .
关键字是与bash source
命令兼容的POSIX。