Jak przenieść i odtworzyć folder jednocześnie?

9

Mam folder o nazwie statisticsna serwerze Ubuntu, w którym pliki danych są regularnie przechowywane. Jak mogę zmienić nazwę statisticsfolderu na backup-xxpodczas ponownego tworzenia statisticsfolderu, aby był dostępny do przechowywania nowych plików?

Pliki w statisticsfolderze są tworzone przez PHP file_put_contents.

Wolę zmienić nazwę folderu, ponieważ w folderze znajduje się wiele plików statistics.

Googlebot
źródło
Na początku myślałem, że masz na myśli „jednocześnie”, że operacja powinna być „atomowa” (o ile to możliwe).
phk
@phk Tak, właśnie o to mi chodziło.
Googlebot
Nawiasem mówiąc, poprawna terminologia to „katalog”, a nie „folder”.
Berk Özbalcı

Odpowiedzi:

7
mv statistics backup-xx && mkdir statistics

Spowodowałoby to zmianę nazwy istniejącego statisticskatalogu na backup-xx, a jeśli się powiedzie, kontynuowałoby tworzenie nowego statisticskatalogu.

Aby uzyskać bardziej atomową operację, rozważ utworzenie katalogu statistics-001(lub podobnego, może przez zastąpienie 001dzisiejszą datą w odpowiednim formacie) i dowiązanie symboliczne do niego o nazwie statistics:

mkdir statistics-001
ln -s statistics-001 statistics

Jeśli chcesz to „obrócić”, aby nowe dane trafiły do ​​czystego katalogu, najpierw utwórz katalog, a następnie ponownie utwórz statisticsłącze do niego:

mkdir statistics-002
ln -sf statistics-002 statistics

mv statistics-001 backup-001

W ten sposób, każdy program zapisu do statisticskatalogu (czyli katalog, że ten symboliczny dowiązanie) nigdy nie będzie 1 uda się go znaleźć.

Jeśli potrzebujesz specjalnych uprawnień lub praw własności do katalogu, który statisticswskazuje, ustaw je przed (ponownym) utworzeniem łącza.

1 A raczej, w ten sposób czas, w którym program byłby bez prawidłowego katalogu docelowego, został zminimalizowany tak bardzo, jak to praktycznie możliwe, przy użyciu standardowych narzędzi uniksowych.

Kusalananda
źródło
1
Możesz także chcieć chown --reference=backup-xx statistics ; chmod --reference=backup-xx statisticsustawić własność i uprawnienia. Idealnie zrobiłbyś to przed zmianą nazwy, więc mkdir new ; chown ; chmod ; mv stats backup ; mv new statswpisz proces.
Stephen Harris
@StephenHarris Tak, w systemach, które mają te flagi.
Kusalananda
To jednak nie jest atomowe. Jest zbliżony do atomowego, ale niezupełnie.
CVn
@ MichaelKjörling Naprawiono.
Kusalananda
ln -sfnie jest atomowy. Określono, aby rozłączyć stare dowiązanie symboliczne, a następnie utworzyć nowe, niekoniecznie atomowe. Zamiast tego musisz utworzyć dodatkowe tymczasowe dowiązanie symboliczne i użyć renamefunkcji ( mvna przykład za pomocą polecenia), aby atomowo zastąpić stare. Zobacz moje podejście do tego tutaj: git.musl-libc.org/cgit/musl/tree/tools/…
R .. GitHub ZATRZYMAJ
12

Nie ma możliwości atomowego zastąpienia katalogu innym katalogiem. Możesz przenieść stary katalog, a następnie utworzyć nowy katalog:

mv statistics backup-xx
mkdir statistics

Ale pozostawia to niewielkie okno czasu, podczas którego statisticsnie istnieje. Jest to problem, jeśli jakiś proces może w dowolnym momencie upuścić pliki do katalogu.

Aby skutecznie atomowo zastąpić katalog, musisz użyć dowiązań symbolicznych. Utwórz katalog, którego nazwa obejmuje przedział czasowy od początku:

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

(lub jakkolwiek chcesz wybrać konwencję nazewnictwa katalogów). Utwórz dowiązanie symboliczne o ustalonej nazwie do bieżącej lokalizacji:

ln -s  statistics

Aby zastąpić katalog, najpierw utwórz nowy katalog i nowy link symboliczny, a następnie przenieś go, aby zastąpić stary link symboliczny. Zauważ, że ani zwykły mvsymboliczny link, ani zwykły ln -snie zrobią tego: utworzyłyby pozycję w katalogu docelowym. Coreutils GNU również ln -snfnie jest odpowiednie, ponieważ usuwa istniejące dowiązanie symboliczne przed utworzeniem nowego, co pozostawia małe okno czasowe, w którym ścieżka nie istnieje. Możesz użyć GNU coreutils mv -Tna nowym dowiązaniu symbolicznym.

new_dir="statistics-$(date +%Y%m%d)"
mkdir "$new_dir"
ln -s statistics.new
mv -Tf statistics.new statistics
Gilles „SO- przestań być zły”
źródło
busyboxln -sftakże nie jest atomowy, nie znam żadnej implementacji.
phk
1
Oprócz komentarzy phk dowiązania symboliczne również nie są w 100% bezpieczne, ponieważ działający proces może nadal mieć otwarty deskryptor pliku katalogu (cel dowiązania symbolicznego) i może tworzyć więcej nowych plików w katalogu o zmienionej nazwie (pomyśl o openat()lub CWD). Chciałbym tylko przenieść zawartość katalogu do nowego. Jest to nadal niebezpieczne w przypadku otwartych plików, ale nieco lepsze. Wątpliwe użycie, logrotatektóre powinno najlepiej respektować takie problemy.
rudimeier
1
@phk symlinkWywołanie systemowe nie zastąpi istniejącego pliku, więc niestety bezpośrednie przełączenie dowiązania symbolicznego nie jest atomowe, niestety. renameWywołanie systemowe zastąpi istniejący plik, ale irytująco nie ma przenośny sposób to zrobić w powłoce; jest to możliwe dzięki coreutils GNU dzięki tej -Topcji.
Gilles 'SO - przestań być zły'
3

W ogóle nie zmieniaj nazwy katalogu. Powiedziałeś, że wolisz zmienić nazwę katalogu, ponieważ zawiera on wiele plików. Jedynym powodem, dla którego mogę o tym pomyśleć, jest to, że kopiowanie plików potrwa zbyt długo. Jednak przenoszenie (tj. Zmiana nazwy) plików jest natychmiastowe, o ile są one przenoszone do lokalizacji w tym samym systemie plików. Zakładam, że właśnie to robisz, ponieważ jeśli zmieniasz systemy plików, mvzajmie to tyle samo czasu, cpbez względu na to, czy przenosi katalog, czy jego zawartość.

Więc po prostu wykonaj:

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

Jeśli potrzebujesz również ukrytych plików, możesz:

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

Lub, jeśli używasz bash:

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

W ten sposób katalog jest zawsze obecny, ale nadal przenosisz jego zawartość w prosty i szybki sposób.

terdon
źródło
1

Możesz przenieść zawartość folderu statystyk do nowo utworzonego katalogu zamiast przenosić sam folder. Jeśli przeniesiesz cały folder, musisz uruchomić inne polecenie, aby zmienić uprawnienia do katalogu.

mkdir -p <path>/backup-xxx
mv statistics/* <path>/backup-xxx/.
Kiran Kumar Annam
źródło