shell 重定向位置的区别
shell difference between redirect position
这两行有区别吗?
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 第一个只在 for 循环之外生成 I/O OP。
但是,如果我输入 tail -f /tmp/output.txt
,其行为方式完全相同。
如果他们成功了,他们也会这样做。但是,如果它们因任何原因失败,可能会有显着差异。
第一个:
for ...; do
# things
done >> file
这将在循环完成后重定向到文件。但是,只要 Bash 决定刷新缓冲区,它就可能发生。
想象一下在第 3 次迭代后出现故障:您无法判断文件中存储了哪些内容。
第二个:
for ...; do
# things >> file
done
这将在每次迭代时重定向到该文件。
假设在第 3 次迭代后出现问题:您确定前两个循环已正确存储在文件中。
来自How to redirect output from an infinite-loop program:
If your program is using the standard output functions (e.g. puts
,
printf
and friends from stdio.h
in C, cout << …
in C++, print
in many high-level languages), then its output is
buffered:
characters accumulate in a memory zone which is called a buffer; when
there's too much data in the buffer, the contents of the buffer is
printed (it's “flushed”) and the buffer becomes empty (ready to be
filled again). If your program doesn't produce much output, it may not
have filled its buffer yet.
此外,来自 the answer you link:
Placing the redirection operator outside the loop doubles the
performance when writing 500000 lines (on my system).
这是有道理的:如果你必须在每个循环中刷新,那么它比让 Bash 在觉得方便的时候刷新要花费更多的时间。一次写五行比一次写一行容易
还有一个没有提到的重要区别:>>
每次都打开文件进行写入。这会显着影响性能。
此外,如果 /tmp/output.txt
在循环 运行 时被删除,echo ... >> /tmp/output.txt
将使用新内容重新创建文件,而 for ... done >> /tmp/output.txt
将继续添加数据到同一个文件。
记住这一点很重要,尤其是当我们处理硬链接或临时文件时(通常,我们会在创建临时文件后立即取消链接,以避免在 Bash 脚本退出时出现过时文件没想到)。
这两行有区别吗?
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 第一个只在 for 循环之外生成 I/O OP。
但是,如果我输入 tail -f /tmp/output.txt
,其行为方式完全相同。
如果他们成功了,他们也会这样做。但是,如果它们因任何原因失败,可能会有显着差异。
第一个:
for ...; do
# things
done >> file
这将在循环完成后重定向到文件。但是,只要 Bash 决定刷新缓冲区,它就可能发生。
想象一下在第 3 次迭代后出现故障:您无法判断文件中存储了哪些内容。
第二个:
for ...; do
# things >> file
done
这将在每次迭代时重定向到该文件。
假设在第 3 次迭代后出现问题:您确定前两个循环已正确存储在文件中。
来自How to redirect output from an infinite-loop program:
If your program is using the standard output functions (e.g.
puts
,printf
and friends fromstdio.h
in C,cout << …
in C++,
此外,来自 the answer you link:
Placing the redirection operator outside the loop doubles the performance when writing 500000 lines (on my system).
这是有道理的:如果你必须在每个循环中刷新,那么它比让 Bash 在觉得方便的时候刷新要花费更多的时间。一次写五行比一次写一行容易
还有一个没有提到的重要区别:>>
每次都打开文件进行写入。这会显着影响性能。
此外,如果 /tmp/output.txt
在循环 运行 时被删除,echo ... >> /tmp/output.txt
将使用新内容重新创建文件,而 for ... done >> /tmp/output.txt
将继续添加数据到同一个文件。
记住这一点很重要,尤其是当我们处理硬链接或临时文件时(通常,我们会在创建临时文件后立即取消链接,以避免在 Bash 脚本退出时出现过时文件没想到)。