将标准输出重定向到您没有写权限的文件

Mic*_*zek 125 shell permissions io sudo io-redirection

当您尝试在没有写入权限的情况下修改文件时,您会收到错误消息:

> touch /tmp/foo && sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Run Code Online (Sandbox Code Playgroud)

Sudoing 没有帮助,因为它以 root 身份运行命令,但 shell 处理重定向 stdout 并以您的方式打开文件:

> sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Run Code Online (Sandbox Code Playgroud)

除了以root身份打开shell并以这种方式操作文件之外,是否有一种简单的方法可以将stdout重定向到您无权写入的文件?

> sudo su
# echo test > /tmp/foo
Run Code Online (Sandbox Code Playgroud)

Ger*_*ert 131

是的,使用tee. 于是echo test > /tmp/foo变成

echo test | sudo tee /tmp/foo
Run Code Online (Sandbox Code Playgroud)

您还可以附加 ( >>)

echo test | sudo tee -a /tmp/foo
Run Code Online (Sandbox Code Playgroud)

  • Tee 也会输出到 stdout;有时您不希望内容填满屏幕。要解决此问题,请执行`echo test | 须藤三通/tmp/foo > /dev/null` (34认同)

小智 27

用输出替换文件的内容echo(如>外壳重定向操作符)。

echo test | sudo dd of=/tmp/foo
Run Code Online (Sandbox Code Playgroud)

seek在不截断的情况下写入文件(在开始时,尽管您可以使用以不同的偏移量输出)(如1<>Bourne shell 运算符):

echo test | sudo dd of=/tmp/foo conv=notrunc
Run Code Online (Sandbox Code Playgroud)

>>使用 GNU附加到文件(如)dd

echo test | sudo dd of=/tmp/foo oflag=append conv=notrunc
Run Code Online (Sandbox Code Playgroud)

还参见GNUddconv=excl,以避免(像重挫现有文件set -o noclobber中POSIX壳)和conv=nocreat在相反的(仅更新现有的文件)。

  • dd 在非模糊 bs=1 的情况下是可靠的 (5认同)
  • 我可能不得不收回它;[`dd` 不可靠](https://unix.stackexchange.com/questions/17295/when-is-dd-suitable-for-copying-data-or-when-are-read-and-write-部分),除非您使用晦涩的 GNU-only 选项`iflag=fullblock oflag=fullblock`,这消除了这个答案的优雅。我会坚持使用'tee'。 (2认同)
  • @umeboshi 但只有当您有足够的经验知道自己在做什么时才可靠。如果只犯了一个*小*错误,对于`dd`可能是相当危险的(如果不是说:毁灭性的)。所以对于新用户,我宁愿推荐`tee` 方法安全。 (2认同)

phu*_*ehe 14

tee 可能是最好的选择,但根据您的情况,这样的事情可能就足够了:

sudo sh -c 'echo test > /tmp/foo'
Run Code Online (Sandbox Code Playgroud)


use*_*own 5

虽然我同意,这| sudo tee是规范的方式,有时sed(这里假设 GNU sed)可能会起作用:

cat sudotest 
line 1

sudo sed -i '1iitest' sudotest && cat sudotest 
itest
line 1

sudo sed -i '$aatest' sudotest && cat sudotest 
itest
line 1
atest
Run Code Online (Sandbox Code Playgroud)

-i就地修改文件。1i表示在第 1 行之前插入$a表示在最后一行之后追加

或复制到 xclipboard:

somecommand | xclip
sudo gedit sudotest
move cursor to desired place, click middle mouse button to insert, save
Run Code Online (Sandbox Code Playgroud)

  • 请注意,[`sed -i` 实际上并不修改文件](/sf/answers/888735711/) - 它创建一个临时文件并在退出时重命名。因此,在管道运行时,您将无法对原始文件执行诸如“tail -f ...”之类的操作并使用“sed -i ...”查看输出 (2认同)