I'm trying to port a Linux bash script to FreeBSD. The script needs to check if a file is open (for writing) before deciding whether or not to take some action.
On Linux, this was easy using the fuser command:
if [[ ! `/usr/bin/fuser "$FILE"` ]]
then
...
fi
However, on FreeBSD the fuser command seems totally broken (borne out by this) and doesn't return any proper exit codes or indeed any useful output to stdout. For example, on a file which is actively being written to:
# fuser file
file:
Edit:
Vladimir Botka's comment:
"Simple test in FreeBSD 12.0 shows":
# tail -f /scratch/test-file`
# fuser /scratch/test-file
/scratch/test-file: 45042
# echo $?
0
# ps ax | grep 45042
45042 0 I+ 0:00.00 tail -f /scratch/test-file
45232 1 R+ 0:00.00 grep 45042
On my FreeBSD box (also FreeBSD 12), the same test yields the following:
# tail -f /scratch/test-file
# fuser /scratch/test-file
/scratch/test-file:
# echo $?
0
Vladimir Botka's comment:
Let's try and test the writing to a file with a simple C program which opens the file, waits for an input and writes the input to the file.
Here is my test on the compiled C code:
# ./a.out
Enter num:
# fuser /scratch/test-file
/scratch/test-file:
# echo $?
0
Therefore, fuser does seem to be broken. However, it only seems broken on my system, not on Vladimir Botka's system, which is strange as they're both FreeBSD 12.
It seems I could use lsof or fstat to get this information but not without some complex parsing of the output which is going to make my script more complicated. I wondered if anyone can point me towards a simple 'yes/no' command to determine whether a file is in use like fuser that will work on FreeBSD?
I conclude that
fuseris broken in FreeBSD. In the end I went with a parse of thefstatoutput to solve the problem.fstatproduces the following output on a file which is being actively written (and there is also another process reading it, hence the two lines):The following bash code tests the file using
fstat, removes the header line (sed), then usesawkto grab the 9th column, that which is concerned with whether the file is open for reading or writing. Agrepthen follows to look for thewwrite flag in any of the lines. If it finds one, it will return true. The whole condition is negated (!) to ensure that the action is only carried out if the file is NOT in use: