为什么我不能用处理后的值覆盖文件?

为什么我不能用处理后的值覆盖文件?

这个问题引发了一个想法,我不确定我是否理解得很好。我知道cat myfile | grep -v mypattern > myfile由于文件句柄的设置方式,使用管道是不可能或不正确的。但是,为什么我们不能简单地使用cat myfile | grep -v mypattern| tee myfile>/dev/null就地修改文件呢?有没有失败的简单例子?

具体来说,它是否会导致损坏,或者更多的是不是就地编辑,而是覆盖?

更新问题,如果答案也考虑到这一点,我将不胜感激:

使用有问题吗cat myfile | grep -v mypattern| bash -c 'rm myfile; cat > myfile'

答案1

不会简单地用处理后的值覆盖文件

问题是你不能保证哪个先执行。因此,您必须延迟取消链接和写入文件,直到您完全确定该文件已打开以供读取。

这将在写入文件之前将文件缓冲在 RAM 中。

cat foo | perl -e 'undef $/; @out=<>; open WRT,">",shift; print WRT @out' foo

优点:保留foo的权限。如果被中断,你并没有丢失原来的 foo.txt 文件。

缺点:foo 必须适合 RAM。

这将打开文件进行读取、删除并cat从中删除。它同时等待文件消失,并在文件消失时再进行处理cat

(rm foo; cat) < foo | (perl -e 'while(-e "foo"){}'; cat >foo)

优点:短。适用于大于 RAM 的文件。

缺点:一启动foo就没有了。

(mv foo bar; cat) < foo | (perl -e 'while(-e "foo"){}'; cat >foo && rm bar)

优点:适用于大于 RAM 的文件。如果失败,foo 将作为备份保留在 bar 中。

答案2

您不能简单地执行此操作,因为该tee命令会覆盖文件,使其更短(可能)并消除该cat命令读取文件中数据的能力。

如果您可以确保诸如tee打开之类的程序新的文件,如果 shell 保证cat首先打开其副本,那么您可以从旧的(实际已删除的)文件复制到新的文件。但有很多假设,但保证很少。

例如,您可能会认为,这cat将首先启动,然后tee再启动(当需要捕获数据时)。但是启动两者,除非在启动tee之前等待输入cat,否则写入可能会失败(因为没有人在等待,并且这些字节无处可去)。让进程等待 aread比等待 a更容易write

相关内容