Можно ли запускать несколько команд mv в одном каталоге (состояние гонки)?

Я перемещаю большое количество файлов (400K +) из одного каталога в другой, и у меня есть следующий скрипт для этого (слишком много файлов для команды mv для работы напрямую):

for file in *; do mv $file .. done 

Если я буду запускать этот сценарий дважды (или более) одновременно, будет ли условие гонки, когда / если команды mv пытаются получить доступ к одному и тому же файлу?

Я огляделся по Сети, но не нашел определенного ответа. Благодаря!

2 Solutions collect form web for “Можно ли запускать несколько команд mv в одном каталоге (состояние гонки)?”

Действительно, есть состояние гонки (которое не причинило бы вреда).

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

Но в целом эта структура – очень плохая идея. * расширяется до отсортированного списка. AFAIK это невозможно отключить. Очевидно, что только сортировка – это кошмар с файлами 400K. См. man bash , раздел «Расширение пути»:

После разделения слов, если параметр -f не установлен, bash сканирует каждое слово для символов *,? И [. Если появляется один из этих символов, это слово рассматривается как шаблон и заменяется алфавитно отсортированным списком имен файлов, соответствующих шаблону.

Кроме того, вы не должны запускать один экземпляр mv на каждый файл, так как вы можете перемещать сразу несколько файлов.

Это лучшее решение (в мире GNU):

 find . -mindepth 1 -maxdepth 1 -exec mv --target-directory=DIRECTORY {} + 

Еще лучше было бы использовать GNU Parallel для вставки нескольких аргументов . По умолчанию Parallel будет запускать n заданий одновременно, причем n – это количество ядер вашего процессора.

При перемещении большого количества файлов, таких как: mv * destdir вы иногда получаете ошибку:

 bash: /bin/mv: Argument list too long 

потому что слишком много файлов. Вместо этого вы можете:

 ls -1 | parallel mv {} destdir 

Это запустит mv для каждого файла. Это можно сделать быстрее, если mv получает столько аргументов, которые будут вписываться в строку:

 ls -1 | parallel -m mv {} destdir 

Параметр -m действительно хорош для перемещения или копирования файлов параллельно:

 -m Multiple arguments. Insert as many arguments as the command line length permits. If multiple jobs are being run in parallel: distribute the arguments evenly among the jobs. Use -j1 to avoid this. 
  • Как удалить файл с помощью команды mv?
  • Почему переименование файла с помощью команды mv изменяет дату и время «изменения» inode?
  • Есть ли способ заставить «mv» терпеть неудачу?
  • Как форматировать файл во время перемещения?
  • В чем смысл mv -f?
  • Подкатегории MV на один уровень, но не root
  • Переименовать файлы в индекс
  • команда прогресса не показывает прогресс mv
  • как перемещать набор файлов в один слой
  • mv .. с путём: куда идет мой файл?
  • Список (или перемещение) только файлов с определенным количеством строк?
  • Linux и Unix - лучшая ОС в мире.