我有一个 bash 脚本,它安装了许多开源库(例如:opencv、octave、ff-mpeg 和 SDL 等),我需要 sudo 权限才能访问大多数文件路径。据我所知,默认情况下 sudo 会话将持续 5 分钟,之后我需要重新输入密码以延长 sudo 访问权限。
在我的脚本中,某些安装可能需要超过 30 分钟,因此我需要一次又一次地重新输入密码。如果我使用 sudo 权限运行脚本,它会安装所有内容而无需输入密码,但问题是,它以 root 用户身份运行脚本,并根据 root 而不是运行脚本的普通用户来扩展脚本内的所有相对路径。
例如,路径 ~/.bashrc 扩展为 /root/.bashrc 而不是 /home/actual_user/.bashrc
答案1
如果HOME
设置了变量,则~
在您的示例中将根据变量进行扩展。通常,变量会导出到环境中。
-E
(保留环境)选项向安全策略表明用户希望保留其现有的环境变量。如果指定了该选项并且用户没有保留环境的权限,则
-E
安全策略可能会返回错误。-E
因此,在脚本中sudo -E your_script
有一种扩展的方法。注意,除 之外的环境变量也将被保留。~/.bashrc
/home/actual_user/.bashrc
HOME
或者你可以只保留这一个变量
sudo HOME="$HOME" your_script
这在我的 Debian 中开箱即用,但请参阅man 8 sudo
并man 5 sudoers
了解如何限制变量。
另一种方法是在脚本开头设置变量。其值可以是硬编码的,也可以作为命令行参数传递。
请注意,运行整个脚本sudo
有缺点:
- 任何错误都会通过提升权限来困扰你。
- 如果你的脚本需要知道实际用户的信息
$HOME
以便创造文件或目录,则创建的对象将归 root 所有。当您想在不使用 的情况下使用它们时,这可能会成为问题sudo
。一般前提是您的主目录中的所有内容都属于您(可能的例外就是例外)。
也许你可以隔离脚本的提升部分,这样在你提供一次密码后它就会完整运行,然后返回到非提升的父脚本进行处理/home/actual_user
。就像这样:
#!/bin/bash
foo1 # runs normally
sudo bash <<EOF
bar1 # runs as if with sudo
bar2 # runs as if with sudo
EOF
foo2 # runs normally
答案2
在 bash 中,波浪号扩展至变量 HOME,只需将此命令放在脚本顶部:
default_user=$(logname 2>/dev/null || echo ${SUDO_USER:-${USER}})
HOME="/home/${default_user}"
使用脚本中的所有波浪符号将通过调用 sudo 扩展到运行脚本的主用户目录,因此您只需运行sudo ./your-script.sh