shaiis.com
shaiis.com

Reputation: 264

How to wait until the file is closed

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

Answers (5)

Adam
Adam

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

perreal
perreal

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

Aaron Digulla
Aaron Digulla

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

Matt Joiner
Matt Joiner

Reputation: 118500

Create a small C program using inotify. The program should:

  1. Create an inotify instance.
  2. Add a watch to the instance for the IN_CLOSE_WRITE event for the file path of interest.
  3. Wait for the event.
  4. Exit with an appropriate code.

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

Fred Foo
Fred Foo

Reputation: 363547

The easy way: let the script execute the program and wait until it's finished.

Upvotes: 2

Related Questions