Jac*_*ack 168 command-line bash sudo
当使用 sudo 允许编辑文件时,我经常收到“权限被拒绝”。
例如,我的鼠标抖动和反应迟钝,所以我想禁用轮询:
sudo echo "options drm_kms_helper poll=N">/etc/modprobe.d/local.conf
Run Code Online (Sandbox Code Playgroud)
系统提示我输入密码,然后得到:
bash: /etc/modprobe.d/local.conf: Permission denied
Run Code Online (Sandbox Code Playgroud)
因此,我尝试使用以下方法进行临时更改以禁用轮询:
sudo echo N> /sys/module/drm_kms_helper/parameters/poll
Run Code Online (Sandbox Code Playgroud)
系统再次回应:
bash: /sys/module/drm_kms_helper/parameters/poll: Permission denied
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
sha*_*anu 206
输出重定向(通过>操作符)由 shell 完成,而不是由echo 完成。您必须以 root 身份登录
sudo -i
Run Code Online (Sandbox Code Playgroud)
然后你可以使用重定向
echo N> /sys/module/drm_kms_helper/parameters/poll
Run Code Online (Sandbox Code Playgroud)
否则,您可以使用 sudo 运行 bash 字符串
sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"
Run Code Online (Sandbox Code Playgroud)
Ser*_*gey 82
输出重定向由调用命令的 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
Run Code Online (Sandbox Code Playgroud)
在上面的测试中,whoami | tee who.txt将创建一个名为who.txt“root”的文件。但是,当调用 shell 中的输出重定向失败时,“who.txt”文件也会丢失,因为该命令没有被调用。
Unt*_*led 66
您可以使用这样的tee命令:
sudo tee /sys/module/drm_kms_helper/parameters/poll <<<10
Run Code Online (Sandbox Code Playgroud)
或者如果它是命令的输出:
echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll
Run Code Online (Sandbox Code Playgroud)
如果您想追加而不是覆盖目标文件的情况——也就是说,要使tee行为类似于>>而不是>——您可以使用tee -a.
koj*_*iro 17
我在这里没有看到的一种方法是在它自己的 shell 中简单地执行整个命令行。该sudo联机帮助页给出了这种方法的一个例子:
制作 /home 分区中目录的使用列表。请注意,这会在子 shell 中运行命令以使 cd 和文件重定向工作。
$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
Run Code Online (Sandbox Code Playgroud)
小智 5
另一种选择是使用临时文件。这在 bash 脚本中很有用。
temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever
Run Code Online (Sandbox Code Playgroud)
sudo dd of=
根据需要附加:
echo inbytes | sudo dd of=outfile oflag=append conv=notrunc
Run Code Online (Sandbox Code Playgroud)
或从头开始重新创建文件:
echo inbytes | sudo dd of=outfile
Run Code Online (Sandbox Code Playgroud)
优点:
tee比没有/dev/null重定向更好sh(但有一个用于重定向的隐式子 shell)dd有许多强大的选项,例如status=progress查看传输进度:如何在使用 cp 复制文件时显示传输进度和速度?有效是因为 sudo 将 stdin 转发到命令。