Як скопіювати всі файли у папку, виключаючи записані файли?


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()що неможливо зробити через дескриптор файлу)).


Питання Shell: Я думаю, що я розумію ваш код за одним винятком. -execПрацює shз однією командою ( -c '...') і {} +каже , що помістити більше одного результату в цій команді в той час. Я не розумію, чому shпісля команди є ще один . Що я пропускаю?
Джо

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