2010-12-15 78 views
1
TMP="$$.FILE" 

#Process puts contents into TMP 

cat "$TMP" | sort | head > "$TMP" 

我已经确定该文件不是空的开始。如果没有> "$TMP",它会输出一些内容,但是当它再次存储到同一个文件中时,它是空的。可能是什么原因?为什么这会导致文件变空?

回答

2

这些进程都是并行运行的,所以在cat有机会读取之前,head命令会截断文件。

要获得您想要的结果,您需要将排序输出写入不同的文件,然后将其移至原始文件。

cat "$TMP" | sort | head > "$TMP".new 
mv "$TMP".new "$TMP" 
+0

+1 - 谢谢你 – Strawberry 2010-12-15 17:02:01

+0

'排序 “$ TMP” |头> “$ TMP”。新&& MV “$ TMP”。新的 “$ TMP”'将继续从重挫的文件!如果出现错误(并且它给猫猫一个休息) – 2010-12-15 20:16:38

3

您无法同时写入和读取文件。这里大概会发生什么:

  1. > "$TMP"导致文件被打开写入,这也会截断文件。
  2. cat "$TMP"从现在读取空白文件。
  3. 文件保持空白。

声称修改文件的命令实际上在封面下执行一些临时文件洗牌。例如,sed -i将处理输入文件并将结果保存到input.tmp,然后在mv input.tmp input末尾覆盖原始文件。你应该遵循这个模型。

+0

我明白了,那么围绕它的解决方案是什么?创建另一个TMP文件? – Strawberry 2010-12-15 17:01:10

1

在发生任何事情之前,最后一个管道将会截断第一个管道读取的文件。那么cat会发生什么情况会尝试读取立即截断的电话号码为head的文件。这是造成这里的问题;该>运营商是一个shell运营商,这意味着“截断这个文件的时候了,然后让进程写它的标准输出到文件中。

在一个相关的说明,您不需要cat这里。

尝试这个代替:

TMP="$$.FILE"  
sort <"$TMP" | head > "$TMP.tmp" 
mv "$TMP.tmp" "$TMP"