@
siteshen #35 文件真的没有被清空吗?看下文件的修改时间?
你写的的 hello.txt 是不是每行都恰好包含字母 a 呢?加一行不含字母 a 的内容试试?
例 1 里的圆括号“()”标记会 fork 一个 shell (暂称为子 shell )来执行。于是命令等价为这样的:
cat hello.txt | grep a | bash -c "sleep 1; cat > hello.txt"
如果没有 sleep 1,那么会立刻在子 shell 里发生文件清空。不过此时 cat 和子 shell 是同时 fork 的,而且子 shell 启动后的初始化及对命令的语法解析会花费一些时间(也就几十毫秒而已)。
如果 hello.txt 文件较小,等到子 shell 开始奉命清空文件时,cat 是有充足的时间读到文件全部内容的。如果文件超出了缓冲区大小(缓冲区默认是 4k,不过程序可以设置其他大小,内核也可能会多预读点内容。),就不保证 cat 能读到正确的内容了。
所以一些软件系统会设计为“对关键文件的修改加锁”,就是为了防止多个进程同时修改某个文件。
典型的代表就是 yum 的 install 子命令。