Как дождаться закрытия файла

У меня есть внешний процесс, который начала писать в файл.
Как написать сценарий, который ждет, пока файл не будет закрыт (когда другой процесс закончен с записью).

5 ответов


есть несколько способов добиться этого:

  • если вы можете, запустите процесс из своего сценария. Сценарий будет продолжаться, когда процесс завершится, и это означает, что он не может больше записывать данные в файл.

  • если вы не можете контролировать процесс, но знаете, что процесс завершается после записи файла, вы можете узнать идентификатор процесса, а затем проверить, работает ли процесс с kill -0 $PID. Если $? is 0 после этого процесс все еще жив.

  • если это невозможно, то можно использовать lsof -np $PID чтобы получить список всех открытых файлов для этого процесса и проверить, есть ли ваш файл в списке. Это несколько медленно, хотя.

[EDIT] обратите внимание, что все эти подходы являются весьма хрупкой. Правильное решение состоит в том, чтобы внешний процесс записывал файл с использованием временного имени, а затем переименовывал его, как только он сделанный.

переименование гарантирует, что все остальные либо видят весь файл со всеми данными, либо ничего.


простой способ: пусть скрипт выполнит программу и дождется ее завершения.


создайте небольшую программу C с помощью inotify. Программа должна:

  1. создать inotify экземпляра.
  2. добавьте часы в экземпляр для IN_CLOSE_WRITE событие для интересующего пути к файлу.
  3. ждать события.
  4. выход с соответствующим кодом.

затем в вашем скрипте вызовите программу с путем к файлу в качестве аргумента.

вы можете расширить это, добавив аргумент timeout, и позволяет указывать различные события.


Это нехорошо,и я чувствую себя грязным, когда пишу это... в /tmp/ФОО.txt-это файл проверяется...

#!/bin/bash

until [ "$( find /proc/*/fd 2> /dev/null | 
   xargs -i{} readlink {} |
   grep -c '^/tmp/foo.txt$' )" == "0" ]; do

   sleep 1;
done;

цикл, пока файл не будет стабильным подходом, это должно работать, если вы ждете результатов эксперимента (поэтому вам не нужна обработка событий в реальном времени):

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