Reputation: 264
I have an external process that start a write to a file.
How do I write script that waits until the file is closed (when the other process done with the writing).
Upvotes: 8
Views: 6338
Reputation: 36703
This isn't nice, and it makes me feel dirty writing it... /tmp/foo.txt is the file being tested...
#!/bin/bash
until [ "$( find /proc/*/fd 2> /dev/null |
xargs -i{} readlink {} |
grep -c '^/tmp/foo.txt$' )" == "0" ]; do
sleep 1;
done;
Upvotes: 1
Reputation: 97948
Loop until file is stable approach, this should work if you are waiting for experiment results (so you don't need real-time event handling):
EXPECTED_WRITE_INTERVAL_SECONDS=1
FILE="file.txt"
while : ; do
omod=$(stat -c %Y $FILE)
# echo "OLD: $omod"
sleep $EXPECTED_WRITE_INTERVAL_SECONDS
nmod=$(stat -c %Y $FILE)
# echo "NEW: $nmod"
if [ $omod == $nmod ] ; then
break
fi
done
Upvotes: 2
Reputation: 328584
There are several ways to achieve this:
If you can, start the process from your script. The script will continue when the process terminates and that means it can't write any more data to the file.
If you can't control the process but you know that the process terminates after writing the file, you can find out the process ID and then check if the process is still running with kill -0 $PID
. If $?
is 0
afterwards, the process is still alive.
If that's not possible, then you can use lsof -np $PID
to get a list of all open files for this process and check if your file is in the list. This is somewhat slow, though.
[EDIT] Note that all these approaches are somewhat brittle. The correct solution is to have the external process write the file using a temporary name and then rename it as soon as it's done.
The rename makes sure that everyone else either sees the whole file with all the data or nothing.
Upvotes: 2
Reputation: 118500
Create a small C program using inotify
. The program should:
inotify
instance.IN_CLOSE_WRITE
event for the file path of interest.Then in your script, invoke the program with the file path as an argument.
You could extend this by adding a timeout argument, and allowing different events to be specified.
Upvotes: 2
Reputation: 363547
The easy way: let the script execute the program and wait until it's finished.
Upvotes: 2