使用管道附加到文件不会附加,而是覆盖

使用管道附加到文件不会附加,而是覆盖

跑步:

cat .bashrc | sed s/HISTFILESIZE=.*/HISTFILESIZE=10000/ >> .bashrc | echo 'HISTTIMEFORMAT="%F %T "' >> .bashrc

我期望 .bashrc 被重复(使用 >> 指令)

然而,没有任何重复。解释是什么?

答案1

我期望 .bashrc 被重复(使用 >> 指令)

文件的内容应该被复制,是的。cat打印文件的内容,sed将其全部完整地传递,并且附加重定向确保打印的内容到达文件的末尾,因此正在读取的部分和正在写入的部分之间不存在部分重叠。

$ cat test.txt
hello
world
$ cat test.txt
hello
world
new line
hello
world
new line

并不是说复制你的内容.bashrc似乎很有用。此外,根据时序的工作方式,cat最终也可能会重新读取新编写的重复部分,从而导致更多(最坏的情况是无限制的)重复。这可能取决于文件大小(除其他外),因为小文件cat更有可能读取整个内容并在写入更多内容之前看到 EOF。

... >> file | echo ...管道有点荒谬,因为左侧的重定向将覆盖连接两个命令的管道,并且echo无论如何都不会从其输入中读取。它还有一个额外的问题,因为管道的各个部分是同时启动的,所以您无法知道是echo在左侧运行之前还是之后写入其输出。

现在,如果您碰巧使用 zsh,情况就会改变。通过set,zsh 会安排进程multios的输出sed两个都到管道和文件。但由于echo不会从管道中读取任何内容(并且可能很快完成),因此当 zsh 的辅助进程写入管道时,它会因 SIGPIPE 信号而终止,并且永远不会抽出时间写入文件。你应该看到类似的东西seq 10 > foo.txt | true,它给了我一个空文件。

所以,就用它... >> file; echo ...代替吧。

如果您想修改文件的一部分,sed -i可能会有用。所以:

sed -i 's/HISTFILESIZE=.*/HISTFILESIZE=10000/' .bashrc
echo 'HISTTIMEFORMAT="%F %T "' >> .bashrc

相关内容