当使用 sudo 允许编辑文件时,我经常会收到“权限被拒绝”的提示。
例如,我的鼠标抖动且反应迟钝,所以我想禁用轮询:
sudo echo "options drm_kms_helper poll=N">/etc/modprobe.d/local.conf
系统提示我输入密码,然后得到:
bash: /etc/modprobe.d/local.conf: Permission denied
因此,我尝试通过以下方式进行临时更改以禁用轮询:
sudo echo N> /sys/module/drm_kms_helper/parameters/poll
系统再次回复:
bash: /sys/module/drm_kms_helper/parameters/poll: Permission denied
有任何想法吗?
答案1
输出重定向(通过>
操作符)由 shell 完成,而不是由回声. 您必须以 root 身份登录
sudo -i
然后你可以使用重定向
echo N> /sys/module/drm_kms_helper/parameters/poll
否则你可以使用 sudo 运行 bash 字符串
sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"
答案2
输出重定向由 shell 完成调用该命令的地方。那么,把所有东西分解成几部分,下面是发生的事情*:
shell 调用
sudo echo "options drm_kms_helper poll=N"
,使用命令行执行sudo
命令echo "options drm_kms_helper poll=N"
sudo 要求输入密码,打开超级用户 shell 并调用
echo "options drm_kms_helper poll=N"
,运行echo
命令并将其传递给"options drm_kms_helper poll=N"
echo 以
root
特权运行,将字符串打印到其标准输出。echo
命令终止,超级用户 shell 退出,sudo
终止调用命令的 shell 收集输出并尝试将其重定向到
/etc/modprobe.d/local.conf
,该目录仅可由 root 写入。它收到“权限被拒绝”错误。
有关解决此问题的方法,请参阅@shantanu 的回答。
(*) - 虽然上述顺序有助于理解命令失败的原因,但实际上事情发生得有些混乱:原始 shell 注意到重定向,并在调用命令之前尝试打开文件进行写入sudo ...
。当打开文件失败时,shell 甚至不会调用应该写入文件的命令(感谢 @PanosRontogiannis 指出这一点)。
这是一个快速测试:
$ touch ./onlyroot.txt
$ sudo chown root:root ./onlyroot.txt
$ sudo bash -c "whoami | tee who.txt" > onlyroot.txt
bash: onlyroot.txt: Permission denied
在上面的测试中,whoami | tee who.txt
将要创建一个名为who.txt
包含单词“root”的文件。但是,当调用 shell 中的输出重定向失败时,“who.txt”文件也会丢失,因为没有调用该命令。
答案3
您可以使用tee
命令如下:
sudo tee /sys/module/drm_kms_helper/parameters/poll <<<10
或者如果它是命令的输出:
echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll
如果您遇到想要附加而不是覆盖目标文件的情况 - 即使其表现tee
得像>>
而不是>
- 您可以使用tee -a
。
答案4
另一个选择是使用临时文件。这在 bash 脚本中很有用。
temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever