重定位之间的shell差异

时间:2015-12-28 13:21:52

标签: linux bash shell io-redirection

这两行之间有什么区别吗?

for i in $(seq 1 10); do echo $i - `date`; sleep 1; done >> /tmp/output.txt

for i in $(seq 1 10); do echo $i - `date` >> /tmp/output.txt ; sleep 1; done

因为Robert told me第一个只使I / O OP在for循环之外。

但如果我输入tail -f /tmp/output.txt,这行为方式完全相同。

2 个答案:

答案 0 :(得分:3)

如果成功,他们也会这样做。但是,如果因任何原因失败,可能会有明显的差异。

第一个:

for ...; do
   # things
done >> file

这将在循环完成后重定向到文件。但是,只要Bash决定刷新缓冲区,就可能发生这种情况。

想象一下,在第3次迭代之后某些事情失败了:你无法分辨出文件中存储的内容。

第二个:

for ...; do
   # things >> file
done

这将在每次迭代时重定向到文件。

想象一下迭代次数3之后出现了一些错误:你确定前两个循环已经正确存储在文件中。

来自How to redirect output from an infinite-loop program

  

如果您的程序使用标准输出功能(例如puts,   printf和来自stdio.h的C朋友,C ++中的cout << …print   在许多高级语言中),然后它的输出是   buffered:   字符在内存区域中累积,称为缓冲区;什么时候   缓冲区中的数据太多,缓冲区的内容是   打印(它被“刷新”)并且缓冲区变空(准备好了)   再次填补)。如果你的程序没有产生太多的输出,它可能不会   已填补其缓冲区。

此外,来自the answer you link

  

将重定向运算符放置在之外的循环加倍   写入500000行(在我的系统上)时的性能。

这是有道理的:如果你必须在每个循环上刷新,那么只要它发现方便就让Bash刷新需要更多的时间。每次写一行比划线更容易。

答案 1 :(得分:0)

还有一个未提及的重要区别:>>每次打开文件进行写入。这可能会影响性能。

此外,如果在循环运行时/tmp/output.txt被删除,echo ... >> /tmp/output.txt将使用新内容重新创建文件,而for ... done >> /tmp/output.txt将继续将数据添加到同一文件中。< / p>

这是要记住的重要事项,特别是如果我们处理硬链接或临时文件(通常,我们在创建它们后立即取消链接临时文件,以避免在Bash脚本意外退出时出现过时的文件)。