我有一个需要 root 权限的脚本。我使用 运行脚本sudo ./script.sh
。脚本的某些部分需要以原始用户身份实际运行,因此我sudo --user=$SUDO_USER
在脚本内部使用来完成该工作。我遇到的问题是我为用户安装了一些实用程序,并且它们的路径附加到我的~/.profile
.我感觉以 sudo 身份运行时 ~/.profile 没有被执行,经 确认sudo --user=$SUDO_USER echo $PATH
。
我可以通过获取 $HOME/.profile 来解决这个问题,但这似乎不是正确的解决方案:
sudo --user=$SUDO_USER source $HOME/.profile; command_i_want_to_run
我是否应该将 $PATH 附加到不同的文件中,以便无论上下文如何都可用?
答案1
我不确定它是否取决于本地 sudoers 策略,但至少在我的 Ubuntu 系统上,您可以使用 sudo-i
或--login
选项来指定登录 shell:
-i, --login
Run the shell specified by the target user's password data‐
base entry as a login shell. This means that login-specific
resource files such as .profile or .login will be read by the
shell.
例如
$ sudo sudo -u steeldriver sh -c 'echo $PATH'
[sudo] password for steeldriver:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
但
$ sudo sudo -iu steeldriver sh -c 'echo $PATH'
/home/steeldriver/bin:/home/steeldriver/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
答案2
bashrc
未获取类似配置文件的原因是 sudo 不运行 shell。它实际上分叉了该进程并执行一些其他操作 - 因此它根本不一定与 shell 相关。如果您想更详细地阅读本文,请Process model
在 中搜索man sudo
。
我可以想到两个可供您选择的明智选择:
- 您可以告诉 sudo 使用登录 shell
- 您可以使用 sudo 执行 bash 并告诉 bash 作为登录 shell
两者以略有不同的方式实现相同的目标。
选项1:
sudo --user=baam -i echo '$PATH'
将告诉 sudo 启动默认 shellbaam
并执行echo $PATH
。请注意原始命令中的引号$PATH
,否则它将被扩展前bash 看到了。
选项2: sudo --user=baam bash -c -l 'echo $PATH'
将使用 sudo 来执行 bash。该-l
标志告诉 bash 充当登录 shell,因此它将 source .profile
.我认为这是更好的解决方案,因为您还可以指定另一个支持该-l
标志的 shell,例如zsh
,因此整体上更加灵活。