我正在为 Linux 制作一个与一些 Ubuntu 系统文件交互的桌面应用程序。因此,在最终用户安装我的软件期间,我需要生成一个文件,/etc/sudoers.d/
让许多脚本在不知道密码的情况下访问系统文件。用户将在安装过程中输入密码,但之后他们不应该这样做。在安装期间,它们将运行give-sudo.sh
,其中包含以下 Bash 代码行:
echo '$USER ALL=(ALL) NOPASSWD: power_off.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: reboot.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: timeout_moss.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: timeout_default.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: set_next_os.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: boot_os_1.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: boot_os_2.sh' >> /etc/sudoers.d/moss-priv
echo '$USER ALL=(ALL) NOPASSWD: give_sudo.sh' >> /etc/sudoers.d/moss-priv
它应该创建一个名为 的文件moss-priv
,并附加使我的脚本运行而无需密码所需的行。我有 8 个脚本,所以我附加了 8 行代码。echo
命令工作正常,生成并读取其moss-priv
内容:
$USER ALL=(ALL) NOPASSWD: power_off.sh
$USER ALL=(ALL) NOPASSWD: reboot.sh
$USER ALL=(ALL) NOPASSWD: timeout_moss.sh
$USER ALL=(ALL) NOPASSWD: timeout_default.sh
$USER ALL=(ALL) NOPASSWD: set_next_os.sh
$USER ALL=(ALL) NOPASSWD: boot_os_1.sh
$USER ALL=(ALL) NOPASSWD: boot_os_2.sh
$USER ALL=(ALL) NOPASSWD: give_sudo.sh
这就是问题发生的时候。它不是为sudo
脚本提供无密码,而是打印一个堆栈跟踪,说明每行 (1-8) 发生错误。不仅如此,如果我sudo
出于任何原因尝试调用,它会显示“授权失败”和堆栈跟踪。因此,我完全失去了sudo
访问权限,甚至无法返回删除导致此问题的文件。我最终不得不重新安装整个操作系统才能让它恢复正常。
现在我sudo
回来了,我准备好在找出moss-priv
文件有什么问题后再次尝试。不过我看不出来,我觉得挺好看的。帮助?
我会对这个问题的解决方案或一个好的替代方法感到满意。
错误:
\>>> /etc/sudoers.d/moss-priv: syntax error near line 1 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 2 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 3 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 4 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 5 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 6 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 7 <<<
\>>> /etc/sudoers.d/moss-priv: syntax error near line 8 <<<
\sudo: parse error in /etc/sudoers.d/moss-priv near line 1
\sudo: no valid sudoers sources found, quitting
\sudo: unable to initialize policy plugin1\\
更新:离开建议的修复程序,我有一个文件give_sudo.sh
:
echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/power_off.sh" >> /etc/sudoers.d/moss-priv
echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/reboot.sh" >> /etc/sudoers.d/moss-priv
echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/timeout_moss.sh" >> /etc/sudoers.d/moss-priv
echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/timeout_default.sh" >> /etc/sudoers.d/moss-priv
echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/set_next_os.sh" >> /etc/sudoers.d/moss-priv
echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/boot_os_1.sh" >> /etc/sudoers.d/moss-priv
echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/boot_os_2.sh" >> /etc/sudoers.d/moss-priv
echo "$SUDO_USER ALL=(ALL) NOPASSWD: /home/jeremiahdgage/Desktop/MOSS/give_sudo" >> /etc/sudoers.d/moss-priv
其中一个脚本说timeout_moss.sh
:
sudo sed -i 's/GRUB_HIDDEN_TIMEOUT=10/GRUB_HIDDEN_TIMEOUT=0.01/g' /etc/default/grub
当我运行它时,bash timeout_moss.sh
(当我在当前目录中时)它仍然要求我输入密码......为什么?
在此之后,文件看起来不太好。您需要提供完全限定的文件名(下面我假设
/sbin/power_off.sh
)。此外$USER
,单引号不展开,它以文字形式获取文件$USER
;我想这不是你想要的。使用双引号并指定完整路径:文件中的行将如下所示:
提示:
/sbin/power_off.sh
如果不可执行,这将不起作用。使其可执行chmod
。$USER
按预期扩展。如果运行安装脚本,sudo
那么您可能需要$SUDO_USER
(请参阅 参考资料man 8 sudo
)。无论如何,建议在写入文件之前检查扩展值是否正常。使用此处的文档(使用未引用的单词,因为您想要
$SUDO_USER
扩展)以更优雅的方式写入文件。此示例将重新创建文件:sudoers
允许您指定整个目录(通过其完整路径,它应该以 开头/
和结尾/
)。将脚本移动到专用目录,您只需将一行添加到/etc/sudoers.d/moss-priv
. 但是,如果您需要您的工具可以通过 访问PATH
,请记住sudo
可以使用单独的PATH
.sudo su -
)并一直保持打开状态。sudo
如果更改后工作正常,请在常规 shell 中测试。如果您失去sudo
访问权限,请使用提升的外壳来解决问题(在您的情况下/etc/sudoers.d/moss-priv
应该删除)。tmux
或screen
作为普通用户并从那里打开提升的外壳。这样,即使您在要修复sudo
访问权限的最关键时刻暂时失去连接,shell 也将继续存在。您将能够跳入提升的外壳,而无需sudo
重新附加到tmux
/screen
。尝试使用双引号:
因此该
$USER
变量将被其内容替换。单引号防止变量被解释。