我有两个并行运行的脚本,它们回显到同一个文件。一个脚本正在回显+++++++++++++++
该文件,而另一个脚本正在回显===========
该文件。
下面是第一个脚本
#!/bin/bash
while [ 1==1 ];
do
echo "+++++++++++++++" >> log.txt
# commands
done
下面是第二个脚本
#!/bin/bash
while [ 1==1 ];
do
echo "===========" >> log.txt
# commands
done
log.txt 文件打印了大约 1400000 行,并且没有一行有像 ++== 之类的混乱大小写?
Linux 是否可以防止这种混乱的发生?如果可以,那么如何以及为什么?
答案1
简单地说,该echo
命令触发一个write
原子系统调用。
请注意,这write
并不保证写入给定的所有字节,但在这种情况下(很少数据),它会写入。
那么理论上write(fd, buffer, n)
可以写入少于n
字节并返回实际写入的写入字节数,以使程序能够写入字节buffer+n
。
管道可能会发生这种情况,因为管道不具有无限的容量。
从write(2)
如果文件是使用 O_APPEND 打开(2)的,则在写入之前首先将文件偏移量设置为文件末尾。文件偏移量的调整和写入操作作为原子步骤执行。
根据 POSIX.1,如果 count 大于 SSIZE_MAX,则结果是实现定义的;有关 Linux 上的上限,请参阅注释。
答案2
你可以尝试一下这个限制:
#!/bin/bash
outer() {
rm log.txt
inner() {
a=$(perl -e 'print "'$1'"x'$2'')
while [ 1==1 ];
do
echo $a >> log.txt
# commands
done
}
export -f inner
timeout 5 bash -c "inner '-' $1" &
timeout 5 bash -c "inner '+' $1" &
wait
sort -u log.txt
}
replace_repeats() {
# Replace
# ---
# with
# -3
perl -pe 's/((.)\2+)/"$2".length$1/e'
}
# This is OK
outer 10 | replace_repeats
outer 100 | replace_repeats
outer 1000 | replace_repeats
outer 4095 | replace_repeats
# This breaks.
# It should give:
# +4096
# -4096
outer 4096 | replace_repeats