当使用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


有什么想法吗?

评论

stackoverflow.com/questions/82256/…

#1 楼

输出重定向(通过>运算符)是由外壳程序完成的,而不是由回声完成的。您必须以root用户身份登录

sudo -i


然后可以使用重定向

echo N> /sys/module/drm_kms_helper/parameters/poll


否则,您可以运行bash带有sudo的字符串

sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"


评论


您无法使用sudo运行echo吗?我得到的结果如何:saji @ laptop:〜$ sudo echo“ Hi” saji的[sudo]密码:嗨

–saji89
2012年12月19日在4:41



您可以写在文件上,在某处回显“某物”。它正在使用管道。这就是问题所在。

– Shantanu
2012年12月19日下午4:55

好的,如果是这样,请更新您的答案以反映仅在这种情况下运行回显才是问题。

–saji89
2012年12月19日下午4:59

您不能简单地将sudo内置的shell内置命令运行为sudo,除非您执行sudo bash -c'echo…'之类的操作。但是,POSIX系统通常在OS X上提供外部回显命令,例如/ bin / echo,而sudo可以在不使用rigamarole的情况下执行。因此,通常运行的echo命令和使用sudo运行的echo命令可能是两个不同但相似的命令。

– kojiro
2012-12-19 13:48



如果是这样,为什么对这个问题的回答暗示了回声? askubuntu.com/questions/840431/…

– Harsha
17-2-26在13:12

#2 楼

输出重定向由已从中调用命令的外壳完成。因此,将所有内容分解为零,这是怎么回事*:


shell调用sudo echo "options drm_kms_helper poll=N",后者通过sudo命令行执行echo "options drm_kms_helper poll=N"命令
echo "options drm_kms_helper poll=N",然后运行echo命令并传递给它"options drm_kms_helper poll=N"
echo,以root特权运行,将字符串打印到其标准输出。
echo命令终止,超级用户外壳退出,sudo终止
外壳从中调用了命令的命令将收集输出,并尝试将其重定向到/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” 。但是,当调用外壳程序中的输出重定向失败时,也会丢失“ who.txt”文件,因为未调用命令。

评论


外壳更有可能自己“分叉”,并在尝试执行“ sudo”之前尝试打开/etc/modprobe.d/local.conf,这意味着您描述的前4个步骤实际上从未发生,因为无法打开文件。

– Panos Rontogiannis
16年5月30日在9:32



@PanosRontogiannis:谢谢,我已经更新了答案

–谢尔盖
16年6月6日在20:35

我赞成,但是恕我直言,(*)必须用答案的第一部分代替,然后第一部分可以用作(*)部分中可能需要它的人的简化形式。

– aderchox
20 Sep 8'7:11



#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

评论


以root身份+1登录对于手动工作是一个坏主意,而对于脚本化任务则是一个非常不好的主意。

–l0b0
2012年12月19日在16:41

另外,如果您不希望sudo tee也打印到stdout,则也可以使用sudo tee / sys / module / drm_kms_helper / parameters / poll> / dev / null。

–法比安夯
15-10-27在7:46

#4 楼

我这里没有提到的一种方法是简单地在自己的shell中执行整个命令行。 sudo联机帮助页本身提供了这种方法的示例:


列出/ home分区中目录的用法列表。请注意,这将在子外壳中运行命令以使cd和文件重定向正常工作。


$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"


评论


哇谢谢。一个简单的解决方案

–弹性
19-10-3在4:43

#5 楼

另一种选择是使用临时文件。这在bash脚本中很有用。

temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever


#6 楼

sudo dd of=

按需添加:

echo inbytes | sudo dd of=outfile oflag=append conv=notrunc


或从头开始重新创建文件:

echo inbytes | sudo dd of=outfile


优点:



tee小,因为没有/dev/null重定向
sh小,因为没有显式的子壳(但隐式的用于子壳)

dd具有许多强大的选项,例如status=progress可以查看传输进度

有效,因为sudo将stdin转发到命令。

评论


很好我们将dd视为我们如何覆盖曾经很棒的文件系统,却没有意识到它也适用于平凡的任务-如果将root命令用于错误的文件/设备,也将造成极大的危害。像sudo tee一样,sudo dd当然也可以在这里使用字符串,例如sudo dd of = outfile <<<'hello world'。 [感谢编辑。注意,如果使用sh -c'cmd',sh是一个子进程,它是一个外壳程序,但实际上不是子外壳程序,除非从某种意义上说,所有外部命令都以一个开头。

– Eliah Kagan
17-10-24在16:00