仅在 bash 中未被访问时才替换文件
Replace file only if not being accessed in bash
我的要求是仅在文件未被访问时才替换文件。我有以下片段:
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
但我怀疑我没有正确处理并发。请提供一些见解和实现此目标的可能方法。
谢谢。
考虑 lsof
。
mvWhenClear() {
while [[ -f "" ]] && lsof ""
do sleep $delay
done
mv "" "" # still allows race condition
}
My requirement is to replace file
only when it is not being accessed.
获得正确的需求可能很难。如果您的实际要求如下,您可以将整个脚本归结为一个命令。
我对实际要求的猜测(不像原来那么严格):
Replace file
without disturbing any programs reading/writing 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
我的要求是仅在文件未被访问时才替换文件。我有以下片段:
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
但我怀疑我没有正确处理并发。请提供一些见解和实现此目标的可能方法。
谢谢。
考虑 lsof
。
mvWhenClear() {
while [[ -f "" ]] && lsof ""
do sleep $delay
done
mv "" "" # still allows race condition
}
My requirement is to replace
file
only when it is not being accessed.
获得正确的需求可能很难。如果您的实际要求如下,您可以将整个脚本归结为一个命令。 我对实际要求的猜测(不像原来那么严格):
Replace
file
without disturbing any programs reading/writingfile
.
如果是这种情况,您可以使用一个非常简洁的行为:在类 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