rm -rf не работает при параллельном удалении

rm -rf не удастся, если что-то пытается удалить одно и то же дерево файлов (я думаю, потому что rm перечисляет файлы сначала, а затем удаляет).

Простой тест:

 # Terminal 1 for i in `seq 1 1000`; do mkdir -p /tmp/dirtest/$i; done # Now at the same time in terminal 1 and 2 rm -rf /tmp/dirtest 

Будет некоторый вывод в stderr, например:

 ... rm: cannot remove directory `/tmp/dirtest/294': No such file or directory rm: cannot remove directory `/tmp/dirtest/297': No such file or directory rm: cannot remove directory `/tmp/dirtest/304': No such file or directory 

Я могу игнорировать весь вывод stderr, перенаправляя его на /dev/null , но удаление /tmp/dirtest фактически не срабатывает! После того, как обе команды закончены, /tmp/dirtest все еще есть.

Как я могу заставить rm правильно удалить дерево каталогов и действительно игнорировать все ошибки?

Насти. Но в некотором смысле вы ищете проблемы, когда два параллельных процесса управляют деревом каталогов. Unix предоставляет примитивы для атомной манипуляции с одним файлом, но не для целых деревьев каталогов.

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

 mv /build/tree /build/tree.rm.$$ mkdir /build/tree rm -rf /build/tree.rm.$$ 

Возможно, вы даже можете сделать rm в фоновом режиме позже, в то время как ваша сборка выполняет некоторые задачи, связанные с процессором.

Мне любопытно, как система сборки закончилась так. Можете ли вы его изменить? Как минимум, вы можете создать флаг, который позволяет скриптам знать, что другой уже выполняет эту работу …

 mkdir /tmp/flag.rmdirtest && rm -rf /tmp/dirtest && rmdir /tmp/flag.rmdirtest 

Было бы лучше перепроектировать вещь, чтобы это не было необходимо.