Too*_*rot 24 pipe io-redirection
有人可能认为
echo foo >a
cat a | rev >a
Run Code Online (Sandbox Code Playgroud)
将离开a
包含oof
; 但它是空的。
rev
于a
?ter*_*don 32
有一个应用程序!在sponge
从命令moreutils
是专为在于此。如果您正在运行 Linux,它可能已经安装,如果没有,请在您的操作系统存储库中搜索sponge
或moreutils
。然后,你可以这样做:
echo foo >a
cat a | rev | sponge a
Run Code Online (Sandbox Code Playgroud)
或者,避免UUoC:
rev a | sponge a
Run Code Online (Sandbox Code Playgroud)
这种行为的原因取决于您的命令运行的顺序。这> a
实际上是执行的第一件事并> file
清空文件。例如:
$ echo "foo" > file
$ cat file
foo
$ > file
$ cat file
$
Run Code Online (Sandbox Code Playgroud)
因此,当您运行时cat a | rev >a
,实际发生的> a
是首先运行该文件,清空该文件,因此当cat a
该文件被执行时,该文件已经是空的。这正是sponge
写作的原因(来自man sponge
,重点是我的):
海绵读取标准输入并将其写出到指定的文件。 与 shell 重定向不同,海绵在写入输出文件之前吸收所有输入。这允许构建读取和写入同一文件的管道。
解决此问题的另一种方法是使用不会截断的写入方法
rev a | dd conv=notrunc of=a
Run Code Online (Sandbox Code Playgroud)
这只有效,因为:
rev 在产生输出之前读取内容并且输出永远不会超过已经读取的数量
新文件内容与原始文件大小相同或更大(在这种情况下为相同大小)
这种方法对于就地修改太大而无法保留临时副本的文件可能很有用。