我正在设置一些环境变量,并尝试通过子进程的子进程访问它们。我正在尝试使用外壳来启动另一个进程。在我的示例中,它只是另一个保持简单内容的 shell 脚本。
我浏览了 shell 文档,并尝试使用-a
标志,但没有奏效。如果我显式地将 env 变量从父级复制到子级,它将起作用。
a.sh
#!/bin/sh
# does not work here
echo $FOO
parent.sh
#!/bin/sh
export FOO=bar
sudo -H -u username nohup sh -c "echo $FOO #works here; sh ./a.sh"
但是,如果我将 FOO 显式传递给内联 shell 脚本,它将起作用
#!/bin/sh
export FOO=bar
sudo -H -u username nohup sh -c "echo $FOO;export FOO=$FOO; sh ./a.sh"
有没有更优雅的解决方案将 env 变量传递给嵌套的子级?
在我的实际实现代码中,它不是我尝试使用的 shell 脚本,而是启动另一个依赖于 env 变量的进程,因此获取脚本是不可行的。
因为 sudo 在启动新进程时默认不保留环境,所以你应该指示它显式保留某个 var:
sudo FOO=100 -H -u username nohup sh -c "sh ./a.sh"
nohup: ignoring input and appending output to ‘nohup.out’
cat nohup.out
100
除非使用-E
选项,否则sudo
不会保留调用方的环境,即使这样,也必须将sudo
配置为允许为给定用户或命令保留环境。
您的第一个示例sudo -H -u username nohup sh -c "echo $FOO #works here; sh ./a.sh"
等效于 (在外壳处理后)
sudo -H -u username nohup sh -c "echo bar; sh ./a.sh"
但是sudo
启动的sh
过程不会在其环境中FOO
。 (不过,sudo -H -u username -E nohup sh -c "sh ./a.sh"
可能有效,具体取决于本地安全策略。-E
是请求,而不是命令。
在外壳处理之后,您的第二个示例是
sudo -H -u username nohup sh -c "echo bar;export FOO=bar; sh ./a.sh"
在这里,sh
不是从调用sudo
的 shell 继承FOO
;相反,你正在运行一个 shell 进程,该进程本身在其环境中定义了一个新的变量FOO
,然后a.sh
继承。