Я хочу переместить большой файл, созданный внешним процессом, как только он будет закрыт.
Является ли эта тестовая команда правильной?
if lsof "/file/name"
then
# file is open, don't touch it!
else
if [ 1 -eq $? ]
then
# file is closed
mv /file/name /other/file/name
else
# lsof failed for some other reason
fi
fi
РЕДАКТИРОВАТЬ: файл представляет собой набор данных, и мне нужно подождать, пока он не будет завершен, чтобы переместить его, чтобы другая программа могла действовать с ним. Вот почему мне нужно знать, выполняется ли внешний процесс с файлом.
linux
shell-script
monitoring
open-files
lsof
Петр Ковач
источник
источник
lsof
вообще, мне просто нужно проверить, если расширение файла не.tmp
. Это делает это тривиальным. Тем не менее я рад , что я спросил мой вопрос , так как я узнал немного оlsof
иinotify
и прочее.Ответы:
Со
lsof
страницы руководстваТак что это предполагает, что ваше
lsof failed for some other reason
предложение никогда не будет выполнено.Вы пытались просто переместить файл, пока ваш внешний процесс все еще открыт? Если каталог назначения находится в той же файловой системе, то проблем с этим не должно быть, если только вам не нужен доступ к нему по исходному пути от третьего процесса, поскольку базовый индекс будет оставаться прежним. Иначе я думаю,
mv
что все равно не получится.Если вам действительно нужно дождаться завершения внешнего процесса с файлом, лучше использовать команду, которая блокирует, а не повторяет опрос. В Linux вы можете использовать
inotifywait
для этого. Например:Если вы должны использовать
lsof
(возможно, для переносимости), вы можете попробовать что-то вроде:Обновить
Как отмечает @JohnWHSmith ниже, самый безопасный дизайн всегда будет использовать
lsof
цикл, как указано выше, поскольку возможно, что более одного процесса будет иметь файл, открытый для записи (в качестве примера можно привести плохо записанный демон индексации, который открывает файлы с чтением / Писать флаг, когда он действительно должен быть только для чтения).inotifywait
все еще может использоваться вместо сна, просто замените строку сна наinotifywait -e close /path/to/file
.источник
inotify
. К сожалению, он не установлен на моей коробке, но я уверен, что где-нибудь найду пакет. См. Мое редактирование по причине, по которой мне нужно закрыть файл: это набор данных, и он должен быть завершен перед дальнейшей обработкой.inotifywait
скрипт не позволит «опрашивать» два часто,lsof
оператору все равно нужно проверять цикл: если файл открывается дважды, однократное закрытие может вызватьinotify
событие, даже если файл не готов к манипулировать (например, в вашем последнем фрагменте кода вашsleep
вызов может быть заменен наinotifywait
).close_write
должно быть в порядке, поскольку только один процесс может одновременно открывать файл для записи. Предполагается, что другой не откроет его сразу после закрытия, но такая же проблема существует приlsof
опросе.CLOSE_WRITE
запускается дважды).В качестве альтернативного подхода, это идеальный случай для канала - второй процесс будет обрабатывать выходные данные первого процесса, как только он станет доступным, а не ждать завершения всего процесса:
Преимущества:
Если у вас нет возможности напрямую создать канал, но у вас есть GNU coreutils, вы можете использовать это:
Это начнёт чтение входного файла с самого начала, независимо от того, как далеко продвинется первый процесс через запись файла (даже если он еще не запущен или уже закончен).
источник
cat
иprocess2
может закончить, прежде чемprocess1
закончится. Они не будут блокировать.