У меня есть два отдельных каталога. Пользователь загружает файл в первый. Theres cronjob работает в фоновом режиме, который копирует файлы каждые 5 минут во второй каталог.
Что произойдет, если пользователь не завершил загрузку и cronjob скопирует файлы? Обратите внимание, что эти два каталога принадлежат разным пользователям, cronjob выполняется как root.
cp
, не будет ждать, пока файл полностью загружен. Поскольку мы ожидаем, что скорость передачи по сети ниже, чем просто копирование файла из одного места в другое на том же хосте, то в определенный моментcp
он достигнет текущего конца файла и прекратит копирование. Решение вашей проблемы может быть простым: сначала пользователь загружает файл с каким-то специально искаженным именем файла (например, с префиксом.
(символ точки). Когда передача завершена, пользователь переименовывает его в исходное имя. Затем задание cron выглядит только для файлов, которые не начинаются с.
.Ответы:
cp
не знает об открытых файлах. Таким образом, если первый пользователь загрузит большой файл и cronjob (или любой другой процесс) начнет копировать этот файл, он будет копировать только столько, сколько уже было написано. Вы можете думать об этом следующим образом -cp
копировать то, что в данный момент находится на диске, независимо от того, завершен ли файл. В противном случае, вы не можете скопировать файлы журнала, например.источник
fuser
+cp
. Такая копия действительно была бы очень ненадежной. Она не будет копировать любой файл, открытый, например, в текстовом редакторе.lsof
? Результат этого должен быть простым в обработке. Вы можете отфильтровать открываемые файлы (скажем, экземпляромcp
) для записи.fuser
конечно), поскольку этот инструмент может отображать не все файлы.cp
не знает, какие другие программы могут иметь открытые файлы. В этом нет магииcp
. Дизайн unix целенаправленно избегает наложения каких-либо блокировок на файлы, если нет веской причины (убедительный смысл в том, что ядру это нужно). В этом разделе см. « Применяет ли блокировка для файла перенаправление вывода в файл?Такие ситуации, когда файл создается производителем и после его завершения потребителем является распространенным явлением. Обычный способ справиться с этим - заставить производителя написать временный файл, который потребитель не будет искать, а затем, как только производитель закончит, переместите файл в место, где его найдет потребитель. Перемещение файла (в той же файловой системе) является атомарной операцией: в какой-то момент, для потребителя, файл изменяется от отсутствия там к тому, чтобы быть там.
Поэтому позаботьтесь о том, чтобы задание на загрузку перемещало файлы в другой каталог после завершения загрузки. Направьте задание cron в этот другой каталог.
источник
Похоже, что вы хотите сделать работу Dir Sync.
Потому что опция -u, --update
cp
Таким образом, вы можете добавить cronjob, например,
cp -auv SOURCEDIR/* DESTDIR
который будет копировать те файлы, время модификации которых изменилось. Это значит,DESTDIR
что в конечном итоге вы получите полную копию, когда загрузка будет завершена.rsync
может сделать ту же работу. например,rsync -av SOURCEDIR/ DESTDIR
.Хотя опция -a применяется, некоторые указанные атрибуты (например, владение) могут быть сохранены только суперпользователем.
См
man cp
,man rsync
для деталей.источник