Bir klasörü aynı anda nasıl taşıyabilir ve yeniden oluşturabilirim?


9

statisticsVeri dosyalarının düzenli olarak saklandığı bir Ubuntu sunucusunda adlandırılan bir klasör var . Nasıl yeniden adlandırabilir statisticsiçin klasör backup-xxyeniden oluşturulurken statisticsklasör yeni dosyalar depolamak için kullanılabilir olması için?

statisticsKlasördeki dosyalar PHP tarafından oluşturulur file_put_contents.

Klasörde birçok dosya olduğundan klasörü yeniden adlandırmayı tercih ederim statistics.


İlk başta Birlikte sanmıştım "aynı anda" operasyonu olması gerektiğini "atom" (bildiğim kadarıyla bu mümkün gibi).
phk

@phk Evet, tam olarak bunu kastettim.
Googlebot

Doğru terminoloji bu arada "klasör" değil "dizin" olacaktır.
Berk Özbalcı

Yanıtlar:


7
mv statistics backup-xx && mkdir statistics

Bu, varolan statisticsdizini yeniden adlandırır backup-xxve başarılı olursa yeni bir statisticsdizin oluşturmaya devam eder .

Daha atomik bir işlem için, bir dizin statistics-001(ya da belki 001bugünün tarihini uygun bir biçimde değiştirerek benzer bir dizin ) ve buna adlandırılan sembolik bir bağlantı oluşturmayı düşünün statistics:

mkdir statistics-001
ln -s statistics-001 statistics

Yeni verilerin temiz bir dizine girmesi için bunu "döndürmek" istediğinizde, önce dizini oluşturun, ardından statisticsbağlantısını yeniden oluşturun :

mkdir statistics-002
ln -sf statistics-002 statistics

mv statistics-001 backup-001

Bu şekilde, statisticsdizine yazılan herhangi bir program (yani, bu sembolik bağlantının işaret ettiği dizin) asla 1'i bulamaz.

Dizinde işaret eden özel izinlere veya sahipliğe ihtiyacınız varsa statistics, bağlantıyı oluşturmadan (yeniden) önce bunları ayarlayın.

1 Ya da daha doğrusu, bu şekilde, bir programın geçerli bir hedef dizini olmadan olacağı zaman, standart Unix araçları kullanılarak mümkün olduğunca en aza indirilir.


1
chown --reference=backup-xx statistics ; chmod --reference=backup-xx statisticsSahiplik ve izinleri ayarlamak için bir de isteyebilirsiniz . Fikri, yeniden adlandırma önce bunu yapacağını, bu yüzden bir mkdir new ; chown ; chmod ; mv stats backup ; mv new statstür işlem.
Stephen Harris

@StephenHarris Evet, bu bayraklara sahip sistemlerde.
Kusalananda

Bu atomik değil. Bu var yakın ama tam değil atomik için.
CVn

@ MichaelKjörling Düzeltti.
Kusalananda

ln -sfatomik değildir. Eski symlink'in bağlantısını kaldırmak ve ardından mutlaka atomik olmayan yeni bir tane yapmak için belirtildi. Bunun yerine, ek bir geçici symlink yapmalı ve eskisini atomik olarak değiştirmek için işlevi (örneğin komut renamearacılığıyla mv) kullanmalısınız. Burada kendisine yaklaşımım bakınız: git.musl-libc.org/cgit/musl/tree/tools/...
R .. GitHub DUR YARDIMCI ICE

12

Bir dizini atomik olarak başka bir dizine değiştirmenin bir yolu yoktur . Eski dizini taşıyabilir ve ardından yeni bir dizin oluşturabilirsiniz:

mv statistics backup-xx
mkdir statistics

Ancak bu statistics, var olmayan küçük bir zaman penceresi bırakır . Bu, bazı işlemlerin herhangi bir zamanda dizindeki dosyaları bırakabilmesi durumunda bir sorundur.

Bir dizini atomik olarak etkili bir şekilde değiştirmek için sembolik bağlantılar kullanmanız gerekir. Başından itibaren zaman aralığını içeren bir dizin oluşturun:

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

(veya dizin adlandırma kuralını seçmek istersiniz). Geçerli konuma sabit bir ada sahip sembolik bir bağlantı oluşturun:

ln -s  statistics

Dizini değiştirmek için, önce yeni bir dizin ve yeni bir sembolik bağlantı oluşturun ve ardından eski sembolik bağın üzerine yazmak için taşıyın. Ne mvsembolik bağlantıdaki bir düzün ne de bir düzlemenin ln -sbunu yapmayacağını unutmayın: hedef dizinde bir giriş oluşturacaklardır. GNU coreutils's ln -snf, yeni bir tane oluşturmadan önce mevcut symlink'i kaldırdığından, yolun mevcut olmadığı küçük bir zaman penceresi bıraktığı için uygun değildir. mv -TYeni sembolik bağlantıda GNU coreutils'i kullanabilirsiniz .

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

busybox' ln -sfAtomik de değil, herhangi bir uygulama bilmiyorum.
phk

1
Phk yorum sembollerinin yanında% 100 güvenli değildir, çünkü çalışan bir işlem hala açık bir dizin dosyası tanımlayıcısına (symlink hedefi) sahip olabilir ve yeniden adlandırılan dizinde daha fazla yeni dosya oluşturabilir (düşünün openat()veya CWD). Ben sadece dizinin içeriğini yenisine taşırdım. Bu, açık dosyalar için hala güvensiz, ancak biraz daha iyi. Kuşkusuz, logrotatebu tür konulara en iyi şekilde saygı duyulması gereken kullanımı kullanın .
rudimeier

1
@ phk symlinkSistem çağrısı mevcut bir dosyanın üzerine yazmaz, bu yüzden maalesef doğrudan sembolik bir bağlantıyı değiştirmek imkansızdır. renameSistem çağrısı varolan dosyanın üzerine, ancak rahatsız edici kabuğunda bunu yapmak için hiçbir taşınabilir yolu yoktur; -Tseçenek sayesinde GNU coreutils ile mümkündür .
Gilles 'SO- kötü olmayı bırak'

3

Dizini hiç yeniden adlandırmayın. Çok sayıda dosya olduğundan dizini yeniden adlandırmayı tercih ettiğini söylediniz. Bunu isteyeceğinizi düşünebilmemin tek nedeni, dosyaları kopyalamanın çok uzun sürmesi. Ancak, aynı dosya sistemindeki bir konuma taşındığı sürece dosyaları taşımak (yani yeniden adlandırmak) anlıktır. Dosya sistemlerini değiştiriyorsanız, bir dizini veya içeriğini taşıyor olsun, bu mvkadar uzun zaman alacağından karınca yaptığınız şey cpbudur.

Yani, sadece şunu yapın:

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

Gizli dosyalar da almanız gerekiyorsa şunları yapabilirsiniz:

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

Veya bash:

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

Bu şekilde, dizin her zaman oradadır, ancak içeriğini basit ve hızlı bir işlemle taşımaya devam edersiniz.


1

İstatistik klasörünün içeriğini, klasörün kendisini taşımak yerine yeni oluşturulan bir dizine taşıyabilirsiniz. Klasörün tamamını taşırsanız, dizin izinlerini değiştirmek için başka bir komut çalıştırmanız gerekir.

mkdir -p <path>/backup-xxx
mv statistics/* <path>/backup-xxx/.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.