Linux下如何在不同用户间传递环境变量?sudo执行场景求助
如何在sudo su切换用户时传递环境变量?
这个问题很常见,核心原因是sudo默认会清除大部分非安全的环境变量,再加上你用了su -(这会启动目标用户的登录shell,重新加载它的~/.bash_profile/~/.bashrc,进一步重置环境),所以原来的var根本没传到anotheruser的环境里。下面给你几个实用的解决方案:
方案1:用sudo的-E选项保留当前环境(不需要登录shell时用)
如果不需要让anotheruser加载登录shell的配置(也就是不用su -的-参数),可以直接用sudo -E来保留当前用户的环境变量,再切换用户执行命令:
sudo -E su anotheruser -c 'echo $var'
-E参数告诉sudo"保留当前用户的环境变量",这样var就能被带到anotheruser的会话里。
方案2:直接在sudo命令中传递变量(支持登录shell)
如果必须用su -来加载目标用户的登录环境,你可以把变量直接定义在sudo的命令环境中,再执行su -:
sudo var="$var" su - anotheruser -c 'echo $var'
这里sudo var="$var"会把当前用户的var值设置到sudo执行的环境里,su -启动的登录shell会继承这个变量(因为它是在sudo的环境中定义的,属于合法的环境变量传递)。
方案3:通过命令参数传递(更通用的方式)
如果担心sudo的环境清理规则,还可以把变量作为命令参数传给目标命令,这种方式不受环境变量限制:
sudo su - anotheruser -c 'echo "$1"' -- "$var"
- 双引号包裹
echo "$1"是为了保留变量值里的空格等特殊字符; --是用来分隔命令和参数,避免变量值以-开头被当成选项;- 最后的
"$var"会作为第一个参数($1)传给-c后的命令。
额外提醒:引号的坑
你原来的命令用了单引号'echo ${var}',单引号里的变量不会被当前shell解析,所以即使环境变量存在,anotheruser的shell也找不到它——因为当前shell没把var的值替换进去。如果用双引号的话,当前shell会先替换变量,但结合sudo su -的环境重置,还是会失效,所以上面的方案更可靠。
内容的提问来源于stack exchange,提问作者gnanda1




