Как скопировать все файлы в папке, кроме файлов, которые записываются?


12

Я загружаю несколько файлов в папку downloadingчерез HTTPie . Сценарий bash предназначен для обработки загруженных файлов, и я попытался скопировать загруженные файлы в другую папку как

find /folder/downloading -type f -exec mv '{}' /folder/downloaded \;

но это также копирует файлы, которые еще не были закончены. Я пытался ограничить передачу старых файлов, добавив -mmin +5в команду. Какая эффективная команда оставить файлы пишутся и передавать только загруженные файлы?


Если вы копируете в ту же файловую систему, и вы устанавливаете загрузчик, чтобы не переименовывать (загрузка в %.partзатем переименовать в%) Затем, если загрузчик ведет себя хорошо (ничего более странного не делает), вы должны иметь возможность переименовывать ( mv) файлы.
ctrl-alt-delor

1
Какую обработку вы пытаетесь сделать? Скорее всего, есть гораздо более простой вариант, например, использование конвейера.
садовник

Ответы:


11

Не очень эффективно, но вы могли бы сделать:

find /folder/downloading -type f -exec sh -c '
  for file do
    lsof -F a "$file" | grep -q w || mv "$file" /folder/downloaded
  done' sh {} +

То есть проверка , что файл не указан в списке с wобрядовым aрежимом ступы в lя sт oперо fИльза перед тем mо vING.

psmiscРеализация , fuserкак правило , находятся на Linux операционных систем на основе имеет -wфункцию (для проверки файлов открыть для записи) , но , к сожалению, только работу с -kубить соответствующие процессы. Тем не менее, кажется, что вы все еще можете использовать его, используя псевдосигнал 0, который ничего не делает:

find /folder/downloading -type f -exec sh -c '
  for file do
    fuser -s -w -k -0 "$file"  || mv "$file" /folder/downloaded
  done' sh {} +

Удалите -s(или даже замените его -v), если вы хотите увидеть, какой процесс (процессы) препятствует перемещению.

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

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

Однако, в зависимости от того, для чего они были предназначены впоследствии, они могут быть сбиты с толку, если после того, как они закончат запись, файла больше не будет (например, если они захотят изменить некоторые атрибуты файла после его загрузки и не через дескриптор файла (как chmod()vs fchmod(), или utimes()который не может быть сделан через дескриптор файла)).


Оболочка вопрос: я думаю, что я понимаю ваш код с одним исключением. Оператор -execзапускается shс одной командой ( -c '...'), и {} +он сообщает, что одновременно нужно вводить в эту команду более одного результата. Чего я не понимаю, так это того, почему shпосле команды есть еще один . Что мне не хватает?
Джо

2
@ Джо, вот что входит в состав встроенного сценария $0. То есть он дает имя этому встроенному скрипту. Это имя может использоваться в сообщениях об ошибках, таких как, <name>: fuser: command not foundнапример, поэтому, shкак правило, в этом случае хорошим выбором будет прояснить, что сообщает об этом сообщении об ошибке (это также будет, если мы вообще не приводим никаких аргументов после рядный скрипт).
Стефан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.