Bazen senaryolarınızın farklı Linux'larda farklı davranmaları gerekir. Bir betiğin hangi Linux sürümünde çalıştığını nasıl belirleyebilirim?
Bazen senaryolarınızın farklı Linux'larda farklı davranmaları gerekir. Bir betiğin hangi Linux sürümünde çalıştığını nasıl belirleyebilirim?
Yanıtlar:
Yapabileceklerinize ve yapamadıklarınıza dair varsayımlara dayanarak varsayımlarda bulunmayın, çünkü bu şekilde delilik (ayrıca "Kullanıcı Aracısı saptaması" bölümüne bakın). Bunun yerine, yapmak istediğiniz şeyin desteklenip desteklenmediğini ve kullanmak istediğiniz herhangi bir komut ya da dosya konumu ile nasıl yapıldığını tespit edin.
Örneğin, bir paket yüklemek istiyorsanız, dpkg veya rpm olup olmadığını kontrol ederek Debian benzeri bir sistemde veya RedHat benzeri bir sistemde olup olmadığınızı tespit edebilirsiniz (ilk önce dpkg'ı kontrol edin, çünkü Debian makineleri onlara rpm komutu ...). Kararınızı yalnızca bir Debian veya RedHat sistemi olup olmadığına değil, buna göre ne yapacağınıza karar verin. Bu şekilde, açıkça programlanmadığınız türev dağıtımlarını otomatik olarak destekleyeceksiniz. Oh, ve paketiniz belirli bağımlılıklar gerektiriyorsa, o zaman bunları da test edin ve kullanıcının ne kaçırdığını bilmesini sağlayın.
Başka bir örnek, ağ arayüzleri ile uğraşmaktır. Bir / etc / network / interfaces dosyası veya / etc / sysconfig / network-scripts dizini olup olmadığına göre ne yapılacağını hesaplayın ve oradan gidin.
Evet, bu daha fazla iş, ancak son on yıl veya daha fazla süre içinde web geliştiricilerinin yaptığı tüm hataları tekrarlamak istemiyorsanız, en baştan akıllıca bir şekilde yapacaksınız.
Çapraz dağıtım yolu yoktur. Ancak:
- Redhat ve arkadaşlar: Test
/etc/redhat-release
edin, içeriği kontrol edin- Debian: Test
/etc/debian_version
et, içerikleri kontrol et- Mandriva ve arkadaşları: Test
/etc/version
edin, içerikleri kontrol edin- Slackware: Test
/etc/slackware-version
et, içerikleri kontrol et
Vb Genel olarak konuşursak, kontrol edin /etc/*-release
ve /etc/*-version
.
Düzenleme: Yıllar boyunca bir araya toplanmış olmalıyım (yaklaşık 6 yıl öncesine kadar etkileyici bir CVS günlüğüne sahiptir.) Olduğu gibi düzgün çalışmayabilir ve yapabilirim. Test edilecek dağıtımları bulmak için canınızı sıkmayın, ancak size iyi bir başlangıç noktası sağlamalıdır. CentOS, Fedora ve Gentoo'da gayet iyi çalışıyor. gyaresu , Debian Lenny'de başarıyla test etti.
#!/bin/bash
get_distribution_type()
{
local dtype
# Assume unknown
dtype="unknown"
# First test against Fedora / RHEL / CentOS / generic Redhat derivative
if [ -r /etc/rc.d/init.d/functions ]; then
source /etc/rc.d/init.d/functions
[ zz`type -t passed 2>/dev/null` == "zzfunction" ] && dtype="redhat"
# Then test against SUSE (must be after Redhat,
# I've seen rc.status on Ubuntu I think? TODO: Recheck that)
elif [ -r /etc/rc.status ]; then
source /etc/rc.status
[ zz`type -t rc_reset 2>/dev/null` == "zzfunction" ] && dtype="suse"
# Then test against Debian, Ubuntu and friends
elif [ -r /lib/lsb/init-functions ]; then
source /lib/lsb/init-functions
[ zz`type -t log_begin_msg 2>/dev/null` == "zzfunction" ] && dtype="debian"
# Then test against Gentoo
elif [ -r /etc/init.d/functions.sh ]; then
source /etc/init.d/functions.sh
[ zz`type -t ebegin 2>/dev/null` == "zzfunction" ] && dtype="gentoo"
# For Slackware we currently just test if /etc/slackware-version exists
# and isn't empty (TODO: Find a better way :)
elif [ -s /etc/slackware-version ]; then
dtype="slackware"
fi
echo $dtype
}
Bunun muhtemelen yalnızca Bash’te düzgün çalışacağını unutmayın. Diğer mermiler için tekrar yazabilirsin.
Olduğu söyleniyor, dağıtım için değil, özellikleri test etmek isteyebilirsiniz. Bunu artık kullanmıyorum, çünkü bakım yükü oldu. Çapraz dağıtım araçlarına ve çözümlerine güvenmek daha kolaydır.
Kavramsal olarak, sırayla:
- Bilinen, "common init script function" dosya tipini çekin. Bunlar dağıtıma özgü. Eğer yoksa, bir sonraki dağıtım kontrolüne atlayın.
- Bu çekirdek betiğinden belirli, var olan, sık kullanılan ve yeniden adlandırılması mümkün olmayan bir fonksiyonun varlığını kontrol edin. Bunu
type
Bash yerleşikini kullanarak yapıyoruz . bu sembol bir işlev isetype -t
dönerfunction
.zz
Çıkışa hazırız ,type -t 2>/dev/null
çünkü ad tanımlanmadıysa çıkış dizgisi boş kalır ve==
operatörün kayıp bir sol eliyle ilgili bir sözdizimi hatası alırız . Kontrol ettiğimiz ad bir işlev değilse, sonraki dağıtım kontrolüne atlayın, aksi takdirde dağıtım türünü bulduk.- Son olarak, dağıtım türünü yankılanır, böylece işlev çıktısı bir durumda kolayca kullanılabilir.
Bunu düz bir komut dosyası olarak çalıştırmayı denemeniz durumunda düzenleyin: Bu komut dosyasının kaynak olması veya diğer komut dosyalarından eklenmesi gerekiyor. Olduğu gibi çalıştırırsanız, hiçbir şeyi kendi başına çıkarmaz. Sınamak için, kaynak ve sonra işlevi çağırmak, örneğin:
source /path/to/this/script.sh
get_distribution_type
bash isteminde.
Düzenleme: Lütfen bu komut dosyasının kök ayrıcalıkları gerektirmediğini unutmayın. Kök olarak çalıştırmamanızı tavsiye ederim. Hiçbir şeye zarar vermemelisin ama buna gerek yok.
CVS günlüğünde ilgili bir posta listesi gönderisine bağlantı bulundu . İnit betiği spagetti paketini açmak için yararlı olmalıdır.
Çekirdek sürümünü çalıştırarak bulabilirsiniz, dağıtma sürümünü uname -a
bulmak dağıtıma bağlıdır.
Ubuntu ve diğer bazı işletim sistemlerinde ' lsb_release -a
/ etc / lsb_release komutunu çalıştırabilir veya okuyabilirsiniz.
Debian, / etc / debian_version konumunda sürümü saklar
Çoğu dağıtım, belirli bir dağılımı belirlemek için benzersiz bir yönteme sahiptir.
Örneğin:
Redhat (And derivatives): /etc/redhat-release
SUSE: /etc/SUSE-release
Orada Linux Standart Bankası veya LSB olarak bilinen bir standart var . / Etc / lsb-release adlı bir dosya veya linux dağıtımınızla ilgili bilgileri geri alacak olan lsb_release adlı bir program olması gerektiğini tanımlar.
lsb_release -a
lsb_release
CentOS 6'da mevcut değil.
python -c 'import platform ; print platform.dist()[0]'
python -c 'import platform; print(platform.dist()[0])'
, çünkü normal python varsayılan olarak python3'e dönerse, bu şekilde de çalışır.
Diğer cevaplara ek olarak: Yalnızca bir dosyayı ayrıştırmak istiyorsanız, çoğu dağıtım tty girişini / etc / issue ile kişiselleştirir:
SUSE Linux Kurumsal Sunucu 10 SP2'ye (i586) Hoşgeldiniz - Çekirdek \ r (\ l).
Ve evet, bunun yetersiz olduğunu biliyorum. :)
Tek yapmanız gereken uname -a
favori kabuğunuzu yazmak. Bu çekirdek adını ve versiyonunu yazdıracak.
Mark, Adam ve Mihai ile aynı fikirdeyim (saygınlık nedeniyle oy kullanamıyorum). LSB ve onun göreli FHS'sine dayanan çözümler çoğu dağıtımda çalışacak ve gelecekte çalışmaya devam etmesi muhtemeldir. LSB ve FHS arkadaşlarınızdır.
Linux sürümü zor bir soru. Eğer buna yakından bakarsak, " uname -r
" ile alabileceğiniz çekirdek versiyonuna sahibiz . Dağıtım sürümü çoğunlukla alakasızdır. Bazı dağıtımlar daha iyidir (Redhat Enterprise Linux gibi kurumsal dağıtımlar). Gentoo gibi diğer dağıtımlar temelde mantıklı bir sürümü olmayan hareketli hedeflerdir. Versiyona dayalı şeyler yapmanız gerekiyorsa, sizinle ilgili ana bileşenlere bir göz atın:
Component Version command
glibc /lib/libc.so.6
gcc gcc --version
X xdpyinfo
libX11 pkg-config --modversion x11
gtk+ pkg-config --modversion gtk+-2.0
qt-4 pkg-config --modversion QtCore
etc...
Grub menüsünü de kontrol edebilirsiniz, genellikle size bir demet dağıtım / sürüm bilgisi verir :-)
FusionInventory , bu bilgileri birçok Linux dağıtımında, aynı zamanda BSD'ler, Windows, MacOS X ve diğer unices de alabilen , platformlar arası hafif bir envanter aracıdır.
Mümkünse, kullanıyorlar lsb_release
(yukarıda birkaç kez bahsedildiği gibi), ancak dağıtım adını ve sürümünü kontrol etmek için çok kullanışlı bir dosya listesine ve düzenli ifadelere sahip değillerse: https://github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / Fusion Envanteri / Temsilci / Görev / Envanter / Giriş / Linux / Dağıtım / NonLSB.pm # L16 .
Toplulukları bu işlevselliği güncel tutacağından, kendi komut dosyalarınızı bu mantıkla yeniden uygulamak yerine, bu bilgileri almak için FusionInventory'i kullanmanızı öneririm. Aracıyı kendi başına kullanabilir (ayrıştırması kolay olan bir XML / JSON dosyası çıkarır) veya gereksinimlerinize bağlı olarak ağınızdaki makineleri GLPI veya Dümen gibi yönetmek için daha geniş bir çözümle birleştirebilirsiniz .