4

Мне нужно написать сценарий оболочки Unix tran.sh, который перемещает входные файлы csv из папки /exp /files в каталог /exp /ready.

Входные файлы csv записываются в папку /exp/files сервером FTP, поведение которого я не могу тривиально изменить. В сценарии оболочки tran.sh мне нужно убедиться, что перед перемещением этого входного файла csv из каталога /exp /files больше никакой другой процесс не записывает в файл.

Как мне это сделать.

5 ответов5

3

Нет портативного способа сделать это. Вы можете попробовать fuser , lsof , inotify , FAM и другие.

3

Попробуйте использовать fuser [FILE] . Он вернет ненулевое значение, если файл не используется.

Вот пример кода, который будет ждать, пока файл станет готовым к перемещению:

#!/bin/sh

FROMDIR='/exp/files'
DESTDIR='/exp/ready'

function move_file_if_ready () {
    if [ -f "$1" ]; then
        while fuser "$1" 2>/dev/null 1>&2 ; do
            sleep 1
        done

        mv "$1" "$DESTDIR"
    fi
}

for "$fn" in "$FROMDIR"/*.csv; do
    move_file_if_ready "$fn"
done
3

Вы можете использовать lsof

r=$(lsof /exp/files )
if [ ! -z "$r" ] ;then
  mv /exp/files/*csv /exp/ready
fi
2

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

Некоторые конкретные примеры проблемных случаев:

  • Если процесс перемещения файлов выполняется от имени другого пользователя, нежели lsof / fuser / etc, информация не гарантируется завершенной
  • Если процесс, выполняющий запись, является сценарием оболочки, он может порождать подпроцесс, который открывает файл, позволяет ему закрыться, порождает другой подпроцесс и т.д. В этом сценарии lsof, fuser и аналогичные инструменты могут на законных основаниях показать, что файл не доступен даже если будет запущен дальнейший подпроцесс, чтобы написать в него позже.

Могут существовать и другие, более тонкие условия гонки - и, тем не менее, lsof, fuser и т.п. не являются инструментами POSIX и доступны не везде.

В соответствии с протоколом требуется, чтобы процессы, записывающие файлы, перемещали их в конечное местоположение по завершении самостоятельно; это единственный безопасный и портативный подход.

РЕДАКТИРОВАТЬ: было выяснено, что файлы пишутся не произвольным процессом (который может закрыть и повторно открыть их), а FTP-сервером. В этом случае incron может использоваться для запуска произвольного скрипта всякий раз, когда файл закрыт в этом каталоге.

0

Я не думаю, что вы можете сделать это без изменения процессов, которые создают эти файлы. Всякий раз, когда у нас возникает такая задача в наших системах, мы гарантируем, что процесс, который создает файл, сделает его исполняемым в самом конце. Так что процесс, который будет перемещаться или постобрабатываться каким-либо другим способом, может проверять наличие исполняемых битов в таких файлах, чтобы убедиться, что исходный процесс завершил работу с файлом.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .