使用 sudo / 无密码执行 shell 脚本

使用 sudo / 无密码执行 shell 脚本

我得到了这一行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

相关内容