My requirement is to replace file only when it is not being accessed. I have following snippet:
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
But I have a doubt that I am not handling concurrency properly. Please give some insights and possible way to achieve this.
Thanks.
Getting requirements right can be hard. In case your actual requirement is the following, you can boil down the whole script to just one command. My guess on the actual requirement (not as strict as the original):
If this is the case, you can use a very neat behavior: In Unix-like systems file descriptors always point to the file (not path) for which they where opened. You can move or even delete the corresponding path. See also How do the UNIX commands mv and rm work with open files?.
Example:
Open a terminal and enter
The first command writes output to
fileand runs in the background. The second command reads the file and continues to print its changing content.Open another terminal and move or delete
file, for instance withWhile executing these commands have a look at the output of
tail -fin the first terminal – it won't be affected by any of these commands. You will never seeoverwritten.Solution For New Requirement:
Because of this behavior you can replace the whole script with just one
mvcommand: