我的要求是仅在不访问文件时替换文件。我有以下代码段:
if [ -f file ]
then
while true
do
if [ -n "$(fuser "file")" ]
then
echo "file is in use..."
else
echo "file is free..."
break
fi
done
fi
{
flock -x 3
mv newfile file
} 3>file
但是我怀疑我没有正确处理并发。请提供一些见解以及实现该目标的可能方法。
谢谢。
答案 0 :(得分:1)
我的要求是仅在不访问
file
时替换它。
正确满足需求可能很困难。如果您的实际要求是以下条件,则可以将整个脚本简化为一个命令。 我对实际需求的猜测(不像最初那样严格):
替换
file
,而不会干扰任何程序读写file
。
如果是这种情况,则可以使用一种非常简洁的行为:在类似Unix的系统中,文件描述符始终指向打开它们的文件(而不是路径)。您可以移动甚至删除相应的路径。另请参见How do the UNIX commands mv and rm work with open files?。
打开一个终端并输入
i=1; while true; do echo $((i++)); sleep 1; done > file &
tail -f file
第一个命令将输出写入file
并在后台运行。第二条命令读取文件并继续打印其更改的内容。
打开另一个终端并移动或删除file
,例如使用
mv file file2
echo overwritten > otherFile
mv otherFile file2
rm file2
echo overwritten > file
echo overwritten > file2
在执行这些命令时,请在第一终端查看tail -f
的输出-不受任何这些命令的影响。您将永远不会看到overwritten
。
由于这种行为,您可以只用一个mv
命令替换整个脚本:
mv newfile file
答案 1 :(得分:0)
考虑lsof
。
mvWhenClear() {
while [[ -f "$1" ]] && lsof "$1"
do sleep $delay
done
mv "$1" "$2" # still allows race condition
}