PID dosyalarından, dolandırıcılardan veya çocukları olmayan süreçleri değerlendirmeye çalışan herhangi bir şeyden kaçının.
UNIX'te SADECE çocuklarınızı beklemenizin çok iyi bir nedeni var. Etrafında çalışmaya çalışan herhangi bir yöntem (ps ayrıştırma, pgrep, bir PID depolamak, ...) kusurludur ve içinde boşluklar vardır. Sadece hayır de .
Bunun yerine, sürecin üst öğesi olmak için sürecinizi izleyen sürece ihtiyacınız vardır. Ne anlama geliyor? Bu, yalnızca işleminizi başlatan işlemin güvenli bir şekilde sona ermesini bekleyebileceği anlamına gelir . Bash'da bu kesinlikle önemsiz.
until myserver; do
echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2
sleep 1
done
Yukarıdaki bash kodu myserver
bir until
döngüde çalışır . İlk satır başlar myserver
ve bitmesini bekler. O bittiğinde, until
onun çıkış durumunu kontrol eder. Çıkış durumu ise 0
, zarif bir şekilde sona erdiği anlamına gelir (bu, bir şekilde kapatmasını istediniz ve başarılı bir şekilde yaptığını gösterir). Bu durumda yeniden başlatmak istemiyoruz (sadece kapatmasını istedik!). Çıkış durumu değilse 0
, until
STDERR üzerinde bir hata mesajı yayan ve 1 saniye sonra döngüyü yeniden başlatan döngü gövdesini çalıştırır .
Neden bir saniye bekleyelim? Çünkü başlangıç dizisi ile ilgili bir sorun varsa myserver
ve hemen çökerse, ellerinizde sürekli yeniden başlatma ve çökme yoğun bir döngüye sahip olacaksınız. sleep 1
Bundan zorlanma alır götürür.
Şimdi yapmanız gereken tek şey bu bash betiğini (eşzamansız olarak, muhtemelen) myserver
başlatmaktır ve gerektiği şekilde izleyip yeniden başlatacaktır. Monitörü önyükleme sırasında başlatmak istiyorsanız (sunucuyu "hayatta kalmayı" başlatarak), @reboot
kuralı kullanarak kullanıcının cron'unda (1) programlayabilirsiniz . Cron kurallarınızı aşağıdakilerle açın crontab
:
crontab -e
Ardından, monitör komut dosyanızı başlatmak için bir kural ekleyin:
@reboot /usr/local/bin/myservermonitor
Alternatif olarak; inittab (5) ve / etc / inittab'a bakın. myserver
Belirli bir başlangıç düzeyinde başlamak ve otomatik olarak yeniden doğmak için oraya bir satır ekleyebilirsiniz .
Düzenle.
Bana neden bazı bilgileri ekleyelim değil PID dosyalarını kullanmak. Çok popüler olsalar da; onlar da çok kusurlu ve sadece doğru şekilde yapmamanızın bir nedeni yok.
Bunu düşün:
PID geri dönüşümü (yanlış işlemi öldürmek):
/etc/init.d/foo start
: Başlat foo
, foo
's PID'sini yaz/var/run/foo.pid
- Bir süre sonra: bir
foo
şekilde ölür.
- Bir süre sonra: başlayan herhangi bir rastgele işlem (onu çağır
bar
) rastgele bir PID alır, foo
eski PID'yi aldığını hayal edin .
- Gittiğini fark ettin
foo
: /etc/init.d/foo/restart
okur /var/run/foo.pid
, hala hayatta olup olmadığını kontrol eder, bulur bar
, düşünür foo
, öldürür, yeni bir başlangıç yapar foo
.
PID dosyaları bayat. PID dosyasının eski olup olmadığını kontrol etmek için aşırı karmaşık (ya da önemsiz değil) mantığına ihtiyacınız var ve böyle bir mantığa karşı yine savunmasız 1.
.
Yazma erişiminiz bile yoksa veya salt okunur bir ortamdaysanız ne olur?
Anlamsız bir aşırı komplikasyondur; yukarıdaki örneğimin ne kadar basit olduğunu görün. Bunu karmaşıklaştırmaya gerek yok.
Ayrıca bkz: PID dosyaları 'doğru' yaparken hala kusurlu mu?
Bu arada; PID dosyalarından bile daha kötü ayrışıyor ps
! Bunu asla yapma.
ps
çok taşınabilir. Hemen hemen her UNIX sisteminde bulduğunuzda; standart dışı çıktılar istiyorsanız argümanları büyük ölçüde değişir. Ve standart çıktı SADECE insan tüketimi için, komut dosyası ayrıştırma için değil!
- Ayrıştırma
ps
, bir sürü yanlış pozitif yol açar. ps aux | grep PID
Örneği ele alın ve şimdi birisinin, artalanınıza baktığınız PID ile aynı olan, argüman olarak bir yerde bir sayı ile işleme başladığını hayal edin! Bir X seansına başladığınızı ve X'in sizinkini öldürmesi için selamladığınızı düşünün. Sadece her türlü kötü.
Süreci kendiniz yönetmek istemiyorsanız; süreçleriniz için monitör görevi görecek bazı mükemmel sistemler var. Örneğin runit'e bakın .