How, in a script, can I determine if a file is currently being written to by another process?

55,779

You can use lsof | grep /absolute/path/to/file.txt to see if a file is open. If the file is open, this command will return status 0, otherwise it will return 256 (1).

Be aware that this command will take a second since there are, normally, a lot of files open at any time.

You can also use lsof -c gedit, for example, to see which file gedit has opened. Restricting the output to one process will reduce execution time to practically nought.

Here's a script to wait:

#!/bin/bash

while :
do
    if ! [[ `lsof -c python3.2 | grep test.py` ]]
    then
        break
    fi
    sleep 0.5
done
echo "done"

This runs while a process 'pyhton3.2' has got the file 'test.py' opened. As soon as the file is closed, it moves on to 'echo done' and exits.

I've put 'sleep 0.5' in there so that the loop doesn't hog the CPU all that badly. Otherwise, it will use 100% cpu.

Bonus There seems to be an easy way to convent odt to pdf:

Thanks to scls19fr on the OOo Forum for this lovely tip. You can convert OpenOffice Writer files to PDF from the command line using unoconv -f pdf input.odt To get unoconv, simply run sudo apt-get install unoconv at the terminal. (rhyshale of rhyshale.wordpress.com)

Share:
55,779

Related videos on Youtube

Peter.O
Author by

Peter.O

Free! Free at last! ... my Windows box died in September 2010 ... and I'm free at last!

Updated on September 17, 2022

Comments

  • Peter.O
    Peter.O over 1 year

    I'm very new to bash scripting, so I might be barking up the wrong tree, but here is my current situation:

    In a script, I start soffice; to convert an odt to a pdf

    It seems that soffice detaches itself from the script's process, and wanders off to do its own thing.. Okay, that's fine; GUI apps tend to do that ...

    However I need to wait until the new pdf has been fully written, as my next step involves processing that new pdf.

    (As far as I know) I can't utilize soffice's process-ID, because it may have already been a running process before my script started: eg. soffice may be already open for normal GUI activity for another unrelated document/presentation/spreadsheet.

    The crux of the matter for me is that before I can proceed, the writing of the new pdf must be finalized...

    Is there some way to determine when a file is no longer open to another process in "write" mode? ...

  • Nick Pascucci
    Nick Pascucci over 13 years
    Wrap this in an until loop and you've got a deal.
  • flo
    flo over 13 years
    Done that. :-) I hope it's not terrible style - haven't bothered to read up on best practices. It works well anyway.
  • Peter.O
    Peter.O over 13 years
    Thanks Stefano... yes, it does work... so it is a good and correct answer.. One a side note, it has highlighted that what is happening in soffice is not as I thought.. It seems that a temporary file is being created and the final file is (perhaps/probably) renamed upon completion... So I'm now looking at that... in which case, I may just need to wait for its *existance... ... and thanks for the link on unoconv .. I'll look into it.. (overall, I'm converting .pdf to multiple ..jpegs one per page)
  • flo
    flo over 13 years
    @fred.bear to wait until a file exists, replace the if-statement with this: if [ -f test.odf ]. (bash script can be so cryptic sometimes...)
  • RubyTuesdayDONO
    RubyTuesdayDONO over 10 years
    try lsof -- /path/to/file instead to avoid the grep'ing
  • Alexander Mills
    Alexander Mills almost 5 years
    With a named pipe, lsof just hangs (waiting for stdin?)