对子 shell 中的输入和父 shell 中的输出使用相同的文件名会发生冲突吗?

对子 shell 中的输入和父 shell 中的输出使用相同的文件名会发生冲突吗?

参考我的这个答案我使用相同的tmp文件作为进程替换的输入,并将输出写入tmp父 shell 中的同一个文件,这在进程替换中读取和由 shell 写入时是否会导致任何中断?

根据评论中的讨论和类似的帖子我发现,好像应该不会冲突吧?

grep -xvFf <(cut -d'/' -f1 tmp) ext >> tmp

评论中相关讨论:

这看起来很优雅,但是不是tmp同时读取和写入吗? –卡西莫多

@Quasímodo不,child-shell 打开只读,并在完成处理思想tmp后完成重定向,然后 shell再次打开写入(但我仍然不是这方面的专家,无法 100% 确认这一点) – α?sнιηgreptmp

@Quasímodostrace grep … 表明它通过grep打开并在完成后关闭,因此在grep完成后shell将输出写入tmp,这样就不会同时中断 – ἀsнιη

答案1

取决于你在做什么。

对于grep -f patterns,在开始读取实际数据文件之前,grep几乎必须预先读取该文件。patterns否则它无法知道第一行是否匹配。所以在这里,你很安全。

当然,如果您使用截断重定向到文件,则在进程替换中的命令读取它之前,它很可能会被截断。但请看下文。


一般来说,在附加模式下重定向输出时,我会担心将输出循环回输入。尝试使用 GNU grep,它足够聪明地发出警告:

$ seq 99999 > foo.txt
$ grep ^1 foo.txt >> foo.txt 
grep: input file ‘foo.txt’ is also the output

但如果我们用进程替换来欺骗它,它就会起作用,并且部分数据会被重复处理:

$ grep ^1 <(cat foo.txt) >> foo.txt
$ grep -Fx 1933 foo.txt
1933
1933
1933
1933

当然应该只有两份副本1933。你的旅费可能会改变。


对于截断重定向,我在 Linux 上进行了以下测试:

echo moi > hello.txt
cat <(cat hello.txt) > hello.txt >&2;

这里,如果在内层猫运行之前处理重定向到hello.txt,结果将是无输出。另一方面,如果cat进程中替换首先运行,它可能会在文件被截断之前读取该文件。循环几次:

for x in {1..999}; do echo moi > hello.txt; cat <(cat hello.txt) 3> hello.txt; done

我的系统上没有输出如果闲置的话moi,但如果同时运行简单的繁忙循环,则输出几次到几十次。 (3>重定向以截断文件而不影响输出。)

相关内容