Ulusal ağda gezinirken karşılaştım Ilginç yazı (ustalıkla açıklandığı için buraya metin olarak getirdim) yazarı bize Bash komut dosyalarımızı kullanarak nasıl daha sağlam hale getireceğimizi gösteriyor Tuzaklar.
Tuzaklarla bash betiklerinizi daha sağlam hale getirin
Her gün altı saatte bir çalışan bir bash betiğiniz olduğunu ve bir noktada başarısız olduğunu veya aynı betiğin aynı anda iki kez çalıştığını hayal edin. Bu iki durum, düzeltilmesi için insan müdahalesini gerektirdiğinden veya belirli zamanlarda ele alınamayacağından sistemi tutarsız bir durumda bıraktığından oldukça rahatsız edicidir. Bunun çözümü, diğerlerinin yanı sıra tuzaklar kullanmaktır.
Tuzaklar, bash komut dosyalarının çıktısını kontrol etmenin basit ve etkili bir yoludur. Aynı başlangıç durumuna geri dönelim, eğer betik manuel olarak durdurulursa, örneğin ctrl-c ile, kesintiye uğrar ve çıkış sinyalini döndürür
INT
ve eğer biterse
kill
o zaman çıktı
TERM
.
Olası tüm çıkış kodları ile görüntülenebilir
kill -l
ancak en çok kullanılanlar tam olarak
INT, DÖNEM, ÇIKIŞ
Komut dosyası, örneğin, dosya senkronizasyonundan oluşuyorsa
rsync
En mantıklı olan şey, komut dosyasının aynı anda çalışmasına izin vermeyen bir kilit dosyasına güvenmektir:
LOCK = "/ var / run / rsync.lock" if [! -e $ KİLİT]; ardından $ LOCK'a dokunun rsync -avz foo bar rm $ LOCK aksi takdirde echo "rsync zaten çalışıyor" fi
Düz İspanyolca'da, önceki komut dosyası, kilit dosyasının var olup olmadığını kontrol eder ve mevcut değilse, onu oluşturur ve daha sonra karşılık gelen komutu çalıştırarak son olarak kilit dosyasını siler. Dosya varsa, komut dosyası kullanıcıya komutun zaten çalıştığını belirten bir mesaj gönderir.
Bununla birlikte, sorunlu bir durum olduğunda, kilit dosyası ortadan kaldırılamayabilir ve istenmeyen etkileri bozabilir. Çözüm çok basit:
LOCK = "/ var / run / rsync.lock" if [! -e $ KİLİT]; sonra tuzak "rm -f $ KİLİT; çıkış" INT TERM ÇIKIŞ $ KİLİT'e dokunun rsync -avz foo bar rm $ KİLİT tuzağı - INT TERM EXIT başka echo "rsync zaten çalışıyor" fi
Bu çözümün özelliği, komutun bir tuzak içine alınmış olmasıdır, böylece bir sinyal alındığında
INT, DÖNEM, ÇIKIŞ
komut dosyası, kilit dosyasını durdurur ve temizler.
Yukarıdaki komut dosyasında, kilit dosyasının doğrulanması ile oluşturulduğu zaman arasında bir rekabet durumu olabileceğini söylemeye değer. Olası bir çözüm, bir yeniden yönlendirme ve bash'ın mevcut bir dosyaya yönlendirmeyen noclobber modunu kullanmak olabilir:
LOCK = "/ var / run / rsync.lock" if (set -o noclobber; echo $$> "$ LOCK") 2> / dev / null; sonra 'rm -f "$ LOCK"' u tuzaklayın; çıkış $? ' INT TERM ÇIKIŞ rsync -avz foo bar rm -f $ LOCK trap - INT TERM EXIT else echo "rsync zaten çalışıyor: $ (cat $ LCK)" fi
İkincisinin tuhaflığı, daha önce de söylediğim gibi, noclobber modunun kullanılması ve kilit dosyasının yürütülmekte olan sürecin PID'sini içermesidir.
Şu gibi başka çözümlerin de olduğunu belirtmekte fayda var.
flock
o
solo
ancak bu yazıda çözümleri bash'ın kendi kaynakları ile paylaşmak istedim. Bununla Tuzaklar hakkında biraz daha bilgi edinebilirsiniz mükemmel rehber.
Harika! Paylaşım için teşekkürler.
Güzel makale, sadece 'echo "yu değiştirin" rsync zaten çalışıyor: $ (cat $ LCK) "' öğesini 'echo" olarak değiştirin rsync zaten çalışıyor: $ (cat $ LOCK) "'
selamlar
Çok ilginç bir makale, evet efendim! Bunu saklıyorum.
Akılda tutulması çok faydalı bir komuttur. Bir gönderide yayınladığım bir komut dosyasında, komutun durdurulduğunda oluşturduğu bazı dosyaları silmek için kullandım.
Çok ilginç, evet efendim.