使用sed管道sponge读写同一文件生成空文件的问题咨询
复现性结论
该问题可以在所有遵循POSIX规范的Shell环境下100%稳定复现,和主机环境、sponge版本、sed的过滤逻辑都没有关联。
问题原因
空文件问题和sponge本身的「吸收全部输入再写入」逻辑无关,本质是Shell的命令执行顺序导致的:
- 当Shell解析包含管道、重定向的整条命令时,会优先处理所有重定向规则,之后才会启动管道两侧的具体命令进程
- 你写的命令里
> file.txt是交给Shell处理的输出重定向,不是传给sponge的参数:Shell在启动sed、sponge进程之前,就会先以截断写入模式打开file.txt,直接把文件内容清空、长度置为0 - 等重定向处理完毕,sed和sponge才会启动:这时候sed去读取
file.txt时,文件已经被清空了,自然读不到任何内容,通过管道传给sponge的输入本身就是空流 - sponge确实是在完整读取所有标准输入内容后才会执行写入操作,但它从启动开始就没有收到任何有效输入,最终写出空文件是完全符合逻辑的结果。
正确用法
sponge的设计初衷就是解决同文件转换时「读和写不能同时打开文件」的问题,使用时需要把目标文件路径直接作为参数传给sponge,不要额外加Shell重定向:
sed 's/\r$//' file.txt | sponge file.txt
这种写法下Shell不会提前触碰、截断目标文件,sponge会在缓存完所有管道输入后,自行打开目标文件完成写入,不会出现空文件问题。
内容的提问来源于stack exchange,提问作者justaguy
相关产品推荐
相关产品推荐

