Bash dosyasındaki atomik yazma işlemlerini gerçekleştirme


13

Bash geçiyor sonra belgelerinde , bu soru bu bana hala net değil bir nasıl bash bir dosyaya atomik yazma (ekleyin) işlemlerini gerçekleştirebilir. Birden çok durumda çalıştırılan bir komut dosyası var ve bir noktada bir dosyaya veri yazmak gerekir:

echo "$RESULT" >> `pwd`/$TEMP_DIR/$OUT_FILE

Eşzamanlı olarak çalışan tüm komut dosyalarından bu dosyaya tüm yazma işlemlerini yapmak nasıl mümkün olur (böylece bir örnekten gelen veriler başka bir örnekten gelen verilerle çakışmaz)?


1
Bilginize ihtiyacınız yok `pwd`; sadece bir nokta ( .) kullanabilirsiniz. Ayrıca , değişkenler içerdiği için tüm dosya adını belirtmelisiniz .
Wildcard

1
Ayrıca FIFO'ları kullanma olasılığını da incelemek isteyebilirsiniz .
Wildcard

@Wildcard Teşekkürler. Ben kullanıyordum pwdgeçerli çalışma dizini konusunda uyarır ve aynı zamanda bir günlük dosyasında girişleri yazma önceki senaryodaki. Şimdi FIFO'lara bakıyorum.
Sebi

1
Aslında bu sitede FIFO'lara daha iyi bir giriş var ; Birkaç dakika önce sağladığım bağlantı, mkfifotam olarak tanıtım seviyesi için değil , POSIX spesifikasyonlarıdır .
Wildcard

FIFO veya dosya olsun, yine de iki örneğin aynı anda yazma ve birbirlerinin çıktılarını bozma riskiyle karşı karşıya kalırsınız.
clacke

Yanıtlar:


10

Görünüşe göre flockinsandan örnekte olduğu gibi kullanmanız gerekiyor ( http://linux.die.net/man/1/flock )

(
flock -x 200

# Put here your commands that must do some writes atomically

) 200>/var/lock/mylockfile 

Ve atomik olması gereken tüm komutlarınızı () içine koyun.


Yazma işlemi atomik olacak olsa da (flock -s 200 # Bazı yazmaları atomik olarak yapması gereken komutlarınızı buraya koyun) 200> / var / lock / mylockfile aynı anda çalışan birden fazla komut dosyasına yayılmış mı? Ya da, tersine, kilit sadece / var / lock / mylockfile ile mi ilgili?
Sebi

1
Betiğiniz / var / lock / mylockfile dosyasını kilitler, ancak betiğinizin yalnızca bir örneği üzerine yazma kilidi alabilir. Diğer örnekler /var/lock/mylockfilekilitlenene kadar bekleyecektir .

-s paylaşılan bir kilittir - okumalar için uygundur, yazma kilidi için -x / -e kullanmanız gerekir. Bağlantı kurduğunuz man sayfasında.
Evan Benn

Bu kodda kilit açma hangi noktada gerçekleşir? Bir şey /var/lock/mylockfiledenilen süreç tarafından yazılır yazılmaz flock -x?
Chris Stryczynski

@ChrisStryczynski Bu örneği (flock -x 200; date; sleep 10; date;) 200>/var/lock/mylockfileiki kabukta çalıştırabilir ve kilit açma işlemlerinin yalnızca () içindeki tüm komutlar yürütüldükten sonra gerçekleştiğini görebilirsiniz (bu bir alt

4

flockkilitli işlemlerin yollarından biridir. Yardımcı program util-linux araç setinin bir parçasıdır ve yalnızca Linux için kullanılabilir. Daha geniş bir platform yelpazesinde bulunan diğer yardımcı programlar, Daniel J. Bernstein'ın setlockdaemontools paketindeki faydası etrafındadır :

  • setlock Daemontools'tan
  • setlock Bruce Guenter'in daemontools-encore sitesinden
  • s6-setlock Laurent Bercot'un s6'sından
  • chpst Gerrit Pape'in runitinden
  • runlock Wayne Marshall'ın perpinden
  • setlock benim nosh araç setimden

Bu araçlar, M. Kurenkov'un cevabında kullanılandan biraz farklı bir paradigma ile çalışır ( flockaynı zamanda istihdam edebilen, ancak bu cevapta olmayan). Biri setlockprogramı, kilitlenmesi gereken komuta zincir yükü için çağırır . setlockkendisi kilit dosyasını açar ve kilitler ve işleminde açık olması için bir dosya tanımlayıcı bırakır. Kilit, bu işlem devam ettiği sürece devam eder (sonraki komut açık dosya tanımlayıcısını bulup kapatarak kilidi açıkça serbest bırakmazsa).

Söz konusu durumda , bir kabuk yerleşik komutu yerine harici bir çağrı başlattığının farkında olarak, çıktı satırını üreten komutu birbirine kenetlemek gerekir :echoecho

setlock mylockfile echo "$ RESULT" >> ./$TEMP_DIR/$OUT_FILE

Bu durumda, çıktı dosyasının ekleme modunda açılıp kapatılması gerekli değildir. Öyle olsaydı, bir benzeri programları kullanarak ya gerektirmektedir kilidi, içinde bu dosyayı açmak zorunda kalacak fdredir/ redirfd:

setlock mylockfile fdredir - uygulama 1 "./$TEMP_DIR/$OUT_FILE" echo "$ RESULT"
hangisi isterse kabuk işlevine dönüşebilir:

outfile () {setlock mylockfile fdredir --ekkat 1 "./$TEMP_DIR/$OUT_FILE" "$ @"; } 
[…]
Outfile echo "$ RESULT"
veya kabuk sözdizimine bağlı kalmak ve kilit altında çalışan ikinci bir kabuk tarafından yorumlanmasını sağlamak, kabuk değişkenleri ortam değişkenleri olarak dışa aktarılmazsa önemsiz bazı alıntılar yapılmasını gerektirir:

setlock mylockfile sh -c 'echo' "$ RESULT" '>> "./'$TEMP_DIR'/'$OUT_FILE'" '

Bu elbette çıktı dosyalarına yazmaktan başka şeyler hakkında genelleme yapar:

setlock mylockfile sh -c '… kilitli; şey …'

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.