![使用 sudo / 无密码执行 shell 脚本](https://linux22.com/image/228419/%E4%BD%BF%E7%94%A8%20sudo%20%2F%20%E6%97%A0%E5%AF%86%E7%A0%81%E6%89%A7%E8%A1%8C%20shell%20%E8%84%9A%E6%9C%AC.png)
我得到了这一行sudoers
:
Cmnd_Alias NVIDIA = /sbin/sh -c 'echo ON > /proc/acpi/bbswitch; modprobe nvidia; modprobe nvidia_drm modeset=1'
user ALL=(ALL) ALL, NOPASSWD: /sbin/systemctl suspend,NVIDIA
我的sudo -l
向我展示:
sudo -l
User user may run the following commands on devbox:
(ALL) ALL, NOPASSWD: /sbin/systemctl suspend, /sbin/sh -c 'echo ON > /proc/acpi/bbswitch; modprobe nvidia; modprobe nvidia_drm modeset\=1'
尽管如此,如果我尝试运行/sbin/sh -c 'echo ON > /proc/acpi/bbswitch; modprobe nvidia; modprobe nvidia_drm modeset=1'
- 仍然提示我输入密码。
我怀疑我在nvidia 负载的争论=
中存在一些关于符号的问题?modeset
答案1
首先,请确保您总是用于visudo
编辑/etc/sudoers
.它会为您执行语法检查,这样您就不太可能最终将自己拒之门外。
现在,使用该命令删除不适当的第一个逗号(在ALL
和之间NOPASSWD
):
(ALL) ALL NOPASSWD: /sbin/systemctl suspend
接下来,要知道您的modeset
命令太复杂,无法在sudoers
文件中直接可靠地定义。考虑这个命令(带或不带sudo
):
sh -c 'date >/tmp/date'
引号将由您自己的(交互式)shell 进行解析,并将带引号的字符串作为单个单词传递。将sh
看到两个参数,-c
并且date >/tmp/date
;该命令永远不会看到引号。同样,这里的引号永远不会被sudo
任何人看到:
sudo sh -c 'date >/tmp/date'
将sudo
看到三个参数sh
, -c
, 和date >/tmp/date
。
因此,我的建议是您创建一个简短的 shell 脚本来执行所需的操作,并添加那到你的sudoers
文件。 (以 root 身份运行以下命令块 - 用于sudo -s
获取 root shell。)
cat >/usr/local/bin/modeset1 <<EOF
#!/bin/sh
echo ON > /proc/acpi/bbswitch
modprobe nvidia
modprobe nvidia_drm modeset=1
EOF
chown root /usr/local/bin/modeset1
chmod a=rx,u+w /usr/local/bin/modeset1
现在sudoers
使用以下visudo
命令添加此行:
(ALL) ALL NOPASSWD: /usr/local/bin/modeset1
一旦/usr/local/bin
添加到您的帐户中,$PATH
您只需使用常用的用户帐户作为标准命令来调用它,
sudo modeset1