Ubuntu以root登录时,如何正确以non_root用户身份执行bash命令?
Ubuntu以root登录时,如何正确以non_root用户身份执行bash命令?
我之前也遇到过一模一样的问题,咱们一步步来拆解解决:
一、先解决echo $USER输出不对的问题
你当前用双引号包裹命令时,$USER会被当前root用户的shell先解析,等传递给non_root的bash时,已经变成了root字符串,自然输出不对。
解决方法很简单,把双引号换成单引号(单引号会阻止当前shell解析变量,让变量在non_root的shell里展开):
sudo -E -u non_root -g non_root -H /bin/bash -c 'echo $USER'
这样执行后,输出就会是non_root了。如果一定要用双引号,也可以转义$:
sudo -E -u non_root -g non_root -H /bin/bash -c "echo \$USER"
二、解决systemctl --user报错的问题
这个报错的核心是:当root直接用sudo -u切换用户时,并没有加载non_root用户的完整登录会话环境,而systemctl --user依赖用户的DBus会话总线和XDG_RUNTIME_DIR等环境变量来工作。
这里有两种可靠的解决方式:
方法1:用-i参数模拟用户登录
-i参数会让sudo模拟non_root用户的登录过程,自动加载用户的.profile/.bashrc配置,同时设置好所有必要的会话环境变量。直接执行:
sudo -i -u non_root systemctl --user disable pulseaudio.service
如果需要在一行执行多个命令,可以这样写:
sudo -i -u non_root bash -c "systemctl --user disable pulseaudio.service && echo '操作完成'"
方法2:手动设置必要的环境变量
如果你不想模拟完整登录,可以手动指定XDG_RUNTIME_DIR(这个变量指向用户的会话运行目录,systemctl需要它找到总线文件)。先获取non_root的UID:
id -u non_root
假设输出是1000,然后执行:
sudo -u non_root -g non_root -H XDG_RUNTIME_DIR="/run/user/1000" systemctl --user disable pulseaudio.service
不过这种方法偶尔可能还需要额外设置DBUS_SESSION_BUS_ADDRESS,不如方法1省心。
总结
- 变量解析问题:用单引号包裹命令,避免当前root shell提前解析变量;
- 会话环境问题:用
sudo -i -u non_root模拟用户登录,是执行systemctl --user这类依赖会话的命令最稳妥的方式。
备注:内容来源于stack exchange,提问作者stackbiz
相关产品推荐
相关产品推荐

