2010-06-16 44 views
29

考虑是这样的:使用与管道命令的输出相同的输入文件可以吗?

cat file | command > file 

这是很好的做法?这可能会覆盖输入文件与我们正在阅读的时间相同,还是始终先在内存中读取,然后通过管道传输到第二个命令?

很显然,我可以使用临时文件作为中间步骤,但我只是想知道..

t=$(mktemp) 
cat file | command > ${t} && mv ${t} file 

回答

44

不,这是不正常。管道中的所有命令同时执行,并且shell在执行命令之前准备重定向。所以,在cat读取文件之前,命令很可能会覆盖文件。

您需要从moreutils获得sponge(1)

+0

感谢,moreutils看起来很有用的!这同样适用于重定向:“命令< file >文件”或甚至进程替换:“命令<(cat file) >文件”? – Amro 2010-06-16 16:30:09

+2

是的,它也适用于这两种情况。请记住,shell可以按任意顺序设置重定向,因此您应该考虑未定义的行为以在单个命令或管道中访问同一文件两次。即使它偶尔也有效,但不能保证。 – Juliano 2010-06-16 16:42:03

3

您也可以使用这样的事情(不推荐,在生产中使用的代码明确的临时文件):

{ rm file && your_command > file; } < file 
0

不仅要你不是你的输出写到你的输入,同时也应避免循环您输出回你的输入。

当大的文件时,我试图

cat *allfastq30 > Sample_All_allfastq30 

,它生成的错误消息:

cat: Sample_All_allfastq30: input file is output file 
相关问题