Як одночасно переміщати та відтворювати папку?


9

У мене на statisticsсервері Ubuntu папка, в якій регулярно зберігаються файли даних. Як я можу перейменувати statisticsпапку під backup-xxчас відновлення statisticsпапки, щоб бути доступною для зберігання нових файлів?

Файли в statisticsпапці створюються PHP file_put_contents.

Я вважаю за краще перейменувати папку, оскільки в папці багато файлів statistics.


Спочатку я подумав, що ви маєте на увазі "одночасно", що операція повинна бути "атомною" (наскільки це можливо).
phk

@phk Так, це саме те, що я мав на увазі.
Googlebot

Правильною термінологією буде, до речі, "каталог", а не "папка".
Berk Özbalcı

Відповіді:


7
mv statistics backup-xx && mkdir statistics

Це дозволить перейменувати існуючий statisticsкаталог у backup-xx, і якщо це вдасться, він би продовжував створювати новий statisticsкаталог.

Для більш атомної операції розгляньте створення каталогу statistics-001(або подібного, можливо, замінивши 001сьогоднішню дату у відповідному форматі), і символічне посилання на нього називається statistics:

mkdir statistics-001
ln -s statistics-001 statistics

Коли ви хочете "повернути" це так, щоб нові дані перейшли в чистий каталог, спершу створіть каталог, а потім відтворіть statisticsпосилання на нього:

mkdir statistics-002
ln -sf statistics-002 statistics

mv statistics-001 backup-001

Таким чином, будь-яка програма, що записується до statisticsкаталогу (тобто до каталогу, на який вказує це символічне посилання), ніколи 1 не зможе його знайти.

Якщо вам потрібні спеціальні дозволи або встановлення права власності на каталог, на який statisticsвказується, встановіть їх перед (повторним) створенням посилання.

1 Точніше, таким чином час, коли програма буде без дійсної цільової каталоги, зводиться максимально максимально, використовуючи стандартні інструменти Unix.


1
Ви також chown --reference=backup-xx statistics ; chmod --reference=backup-xx statisticsможете встановити право власності та дозволи. Ідеально, ви б це зробили перед перейменуванням, тому mkdir new ; chown ; chmod ; mv stats backup ; mv new statsвведіть процес.
Стівен Гарріс

@StephenHarris Так, для систем, які мають ці прапори.
Kusalananda

Але це не атомно. Це близько до атомного, але не зовсім.
CVn

@ MichaelKjörling Виправлено.
Кусалаланда

ln -sfне є атомним. Встановлено, щоб від'єднати старе символьне посилання, а потім зробити нове, яке обов'язково є не атомним. Натомість потрібно створити додатковий тимчасовий посилання та використати renameфункцію (наприклад, за допомогою mvкоманди) для атомної заміни старого. Дивіться мій підхід до нього тут: git.musl-libc.org/cgit/musl/tree/tools/…
R .. GitHub

12

Немає можливості атомно замінити каталог іншим каталогом. Ви можете перемістити старий каталог, а потім створити новий каталог:

mv statistics backup-xx
mkdir statistics

Але це залишає невелике вікно часу, протягом якого statisticsне існує. Це проблема, якщо якийсь процес може в будь-який час скинути файли в каталог.

Для ефективної атомної заміни каталогу потрібно використовувати символічні посилання. Створіть каталог, ім'я якого включає період часу від початку:

mkdir "statistics-$(date +%Y%m%d)"

(або, однак, ви хочете вибрати режим іменування каталогу). Створіть символічне посилання з фіксованим іменем до поточного місця розташування:

ln -s  statistics

Щоб замінити каталог, спершу створіть новий каталог та нове символічне посилання, а потім перемістіть його, щоб перезаписати старе символьне посилання. Зверніть увагу, що це не зробить ані звичайна mvсимвольна посилання, ані звичайна ln -s: вони створили б запис у каталозі цілі. GNU coreutils також ln -snfне підходить, оскільки він видаляє існуюче символьне посилання перед створенням нового, що залишає невелике часове вікно, протягом якого шлях не існує. Ви можете використовувати GNU coreutils mv -Tна новому символічному посиланні.

new_dir="statistics-$(date +%Y%m%d)"
mkdir "$new_dir"
ln -s statistics.new
mv -Tf statistics.new statistics

busybox" ln -sfтакож не є атомним, я не знаю жодної реалізації, яка є.
phk

1
Крім коментарів phk, посилання на коментарі також не є на 100% безпечними, оскільки запущений процес все ще може мати відкритий дескриптор файлів каталогів (ціль символьної посилання), і він може створювати більше нових файлів у перейменованому каталозі (подумайте про openat()або CWD). Я б лише перемістив вміст каталогу до нового. Це все ще небезпечно щодо відкритих файлів, але трохи краще. У сумніві, використання, logrotateяке повинно найкращим чином поважати такі питання.
rudimeier

1
@phk symlinkСистемний виклик не замінить існуючий файл, тому неможливо безпосередньо переключити символічне посилання атомним шляхом, на жаль. renameСистемний виклик буде перезаписувати існуючий файл, але дратівливо немає переноситься способу зробити це в оболонці; це можливо з GNU coreutils завдяки -Tопції.
Жиль "ТАК - перестань бути злим"

3

Не перейменуйте каталог взагалі. Ви сказали, що віддаєте перевагу перейменуванню каталогу, оскільки в ньому багато файлів. Єдина причина, про яку я можу подумати, що ви цього хотіли, - це копіювання файлів задовго. Однак переміщення (тобто перейменування) файлів відбувається миттєво, доки вони переміщуються до місця в тій же файловій системі. Я припускаю, що це ви мусите робити, оскільки якщо ви змінюєте файлові системи, mvце займе стільки ж часу, як і cpнезалежно від того, переміщує це каталог чи його вміст.

Отже, просто робіть:

mkdir backup-xx && mv statistics/* backup-xx

Якщо вам також потрібно отримати приховані файли, ви можете зробити:

mkdir backup-xx && mv statistics/* statistics/.* backup-xx

Або якщо використовується bash:

shopt -s dotglob; mkdir backup-xx && mv statistics/* statistics/.* backup-xx

Таким чином, каталог завжди є, але ви все одно переміщаєте його вміст за допомогою простої та швидкої роботи.


1

Ви можете перемістити вміст папки зі статистикою в новостворений каталог, а не переміщувати саму папку. Якщо ви перемістите всю папку, тоді вам доведеться виконати іншу команду для зміни дозволів каталогу.

mkdir -p <path>/backup-xxx
mv statistics/* <path>/backup-xxx/.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.