可以通过以下方式解决此问题:
cat file | some_sed_command | tee file >/dev/null
没有。
机会file
将被截断掉,但不能保证cat file | some_sed_command | tee file >/dev/null
不会截断file
。
这完全取决于首先处理哪个命令,而不是期望的那样,管道中的命令不是从左到右处理的。不能保证首先选择哪个命令,因此最好将其视为随机选择的,而绝不要依赖shell不选择有问题的命令。
由于在三个命令之间首先选择有问题的命令的几率比在两个命令之间首先选择有问题的命令的几率低,因此file
被截断的可能性较小,但仍然会发生。
script.sh
:
#!/bin/bash
for ((i=0; i<100; i++)); do
cat >file <<-EOF
foo
bar
EOF
cat file |
sed 's/bar/baz/' |
tee file >/dev/null
[ -s file ] &&
echo 'Not truncated' ||
echo 'Truncated'
done |
sort |
uniq -c
rm file
% bash script.sh
93 Not truncated
7 Truncated
% bash script.sh
98 Not truncated
2 Truncated
% bash script.sh
100 Not truncated
因此,切勿使用cat file | some_sed_command | tee file >/dev/null
。sponge
按照Oli建议使用。
作为替代,对于更紧凑的环境和/或相对较小的文件,可以在运行任何命令之前使用here字符串和命令替换来读取文件:
$ cat file
foo
bar
$ for ((i=0; i<100; i++)); do <<<"$(<file)" sed 's/bar/baz/' >file; done
$ cat file
foo
baz