Terkadang skrip Anda perlu berperilaku berbeda di Linux yang berbeda. Bagaimana saya bisa menentukan versi Linux yang menjalankan skrip?
Terkadang skrip Anda perlu berperilaku berbeda di Linux yang berbeda. Bagaimana saya bisa menentukan versi Linux yang menjalankan skrip?
Jawaban:
Jangan mencoba dan membuat asumsi berdasarkan distro tentang apa yang Anda bisa dan tidak bisa lakukan, karena itu ada kegilaan (lihat juga "Deteksi Agen Pengguna"). Alih-alih, deteksi apakah yang ingin Anda lakukan didukung, dan bagaimana hal itu dilakukan oleh perintah atau lokasi file apa pun yang ingin Anda gunakan.
Misalnya, jika Anda ingin menginstal paket, Anda dapat mendeteksi apakah Anda menggunakan sistem seperti Debian atau sistem seperti RedHat dengan memeriksa keberadaan dpkg atau rpm (periksa dpkg terlebih dahulu, karena mesin Debian dapat memiliki perintah rpm pada mereka ...). Buat keputusan tentang apa yang harus dilakukan berdasarkan itu, bukan hanya pada apakah itu sistem Debian atau RedHat. Dengan begitu Anda akan secara otomatis mendukung setiap distro turunan yang tidak Anda programkan secara eksplisit. Oh, dan jika paket Anda memerlukan dependensi tertentu, maka uji juga untuk itu dan beri tahu pengguna apa yang hilang.
Contoh lain adalah mengutak-atik antarmuka jaringan. Cari tahu apa yang harus dilakukan berdasarkan apakah ada file / etc / network / interfaces atau direktori / etc / sysconfig / network-scripts, dan lanjutkan dari sana.
Ya, ini lebih banyak pekerjaan, tetapi kecuali jika Anda ingin membuat kembali semua kesalahan yang telah dilakukan pengembang web selama dekade terakhir atau lebih, Anda akan melakukannya dengan cara yang cerdas sejak awal.
Tidak ada cara distribusi silang. Namun:
- Redhat dan teman-teman: Uji untuk
/etc/redhat-release
, periksa konten- Debian: Tes untuk
/etc/debian_version
, periksa isinya- Mandriva dan teman-teman: Tes untuk
/etc/version
, periksa isinya- Slackware: Uji untuk
/etc/slackware-version
, periksa isinya
Dll. Secara umum, periksa /etc/*-release
dan /etc/*-version
.
Sunting: Menemukan skrip bash lama (1+ tahun) milik saya tergeletak di sekitar yang pasti telah saya kumpulkan selama bertahun-tahun (ini memiliki log CVS yang mengesankan selama 6 tahun.) Mungkin tidak berfungsi dengan baik lagi apa adanya dan saya bisa Jangan repot-repot menemukan distro yang terinstal untuk diuji, tetapi seharusnya memberi Anda titik awal yang baik. Ini berfungsi dengan baik pada CentOS, Fedora dan Gentoo. gyaresu mengujinya dengan sukses di Debian Lenny.
#!/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
}
Perhatikan bahwa ini mungkin hanya akan berfungsi dengan benar di Bash. Anda bisa menulis ulang untuk kerang lain.
Yang sedang berkata, Anda mungkin ingin menguji fitur, bukan untuk distribusi. Saya tidak menggunakan ini lagi hanya karena itu menjadi beban perawatan. Lebih mudah untuk mengandalkan alat dan solusi lintas distribusi.
Secara konseptual, apa yang dilakukannya adalah, dalam rangka:
- Tarik jenis file yang dikenal, "fungsi skrip init umum". Itu adalah distribusi khusus. Jika tidak ada, lewati untuk memeriksa distribusi berikutnya.
- Periksa keberadaan fungsi tertentu, yang diketahui ada, sering digunakan dan tidak mungkin diganti namanya dari skrip inti itu. Kami melakukannya menggunakan
type
Bash builtin.type -t
kembalifunction
jika simbol itu adalah fungsi. Kami menambahkanzz
ke output daritype -t 2>/dev/null
karena jika nama tidak didefinisikan string output akan kosong dan kami akan mendapatkan kesalahan sintaks tentang tangan kiri yang hilang ke==
operator. Jika nama yang baru saja kami periksa bukan fungsi, lewati ke pemeriksaan distribusi berikutnya, kalau tidak kami menemukan jenis distribusi.- Akhirnya, gema tipe distribusi sehingga output fungsi dapat dengan mudah digunakan dalam case .. esac block.
Edit jika Anda mencoba menjalankan ini sebagai skrip langsung: Skrip ini seharusnya bersumber atau disertakan dari skrip lain. Itu tidak menghasilkan apa-apa sendiri jika Anda menjalankan apa adanya. Untuk mengujinya, sumberilah dan aktifkan fungsinya, misalnya:
source /path/to/this/script.sh
get_distribution_type
di bash prompt.
Sunting: Harap dicatat bahwa skrip ini tidak memerlukan hak akses root. Saya mendorong Anda untuk tidak menjalankannya sebagai root. Seharusnya tidak membahayakan apa pun, tetapi tidak perlu.
Menemukan tautan ke pos milis yang relevan di log CVS. Harus berguna dalam membuka skrip skrip init.
Anda dapat menemukan versi kernel dengan menjalankan uname -a
, menemukan versi distro tergantung pada distro.
Di Ubuntu dan beberapa OS lainnya, Anda dapat menjalankan lsb_release -a
atau membaca / etc / lsb_release
Debian menyimpan versi di / etc / debian_version
Kebanyakan distro memiliki metode unik untuk menentukan distribusi tertentu.
Sebagai contoh:
Redhat (And derivatives): /etc/redhat-release
SUSE: /etc/SUSE-release
Ada standar di luar sana yang dikenal sebagai Linux Standard Base atau LSB . Ini mendefinisikan bahwa harus ada file bernama / etc / lsb-release atau program yang disebut lsb_release yang akan mengulang kembali informasi tentang distro linux Anda.
lsb_release -a
lsb_release
tidak ada pada CentOS 6.
python -c 'import platform ; print platform.dist()[0]'
python -c 'import platform; print(platform.dist()[0])'
, karena cara itu juga berfungsi jika python normal default ke python3.
Selain jawaban lain: Jika Anda hanya ingin mem-parsing satu file, sebagian besar distro mempersonalisasi login tty melalui / etc / issue misalnya:
Selamat datang di SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l).
Dan ya saya tahu itu tidak optimal. :)
Yang perlu Anda lakukan adalah mengetikkan uname -a
shell favorit Anda. Itu akan mencetak nama dan versi kernel.
Saya setuju dengan Mark, Adam dan Mihai (tidak dapat memilih karena reputasi yang tidak memadai). Solusi berdasarkan LSB dan FHS relatifnya akan bekerja dengan sebagian besar distribusi dan kemungkinan akan terus bekerja di masa depan. LSB dan FHS adalah teman Anda.
Versi linux adalah pertanyaan yang sulit. Jika kami melihatnya secara sempit, kami memiliki versi kernel yang dapat Anda dapatkan dengan " uname -r
". Versi distribusi sebagian besar tidak sopan. Beberapa distribusi lebih baik (distribusi perusahaan seperti Redhat Enterprise Linux). Distribusi lain seperti Gentoo pada dasarnya adalah memindahkan target yang tidak memiliki versi yang masuk akal sama sekali. Jika Anda perlu melakukan hal-hal berdasarkan versi, lihat komponen utama yang relevan untuk Anda:
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...
Anda juga dapat memeriksa menu Grub, biasanya memberi Anda banyak info distro / versi :-)
FusionInventory adalah alat inventaris ringan lintas platform yang bisa mendapatkan informasi ini di banyak distro Linux, tetapi juga pada BSD, Windows, MacOS X, dan unit lainnya.
Jika tersedia, mereka menggunakan lsb_release
(sebagaimana disebutkan beberapa kali di atas), tetapi jika tidak, mereka memiliki daftar file dan ekspresi reguler yang sangat berguna untuk memeriksa nama dan versi distro: https://github.com/fusinv/fusioninventory-agent/ gumpalan / 2.2.x / lib / FusionInventory / Agent / Task / Inventory / Input / Linux / Distro / NonLSB.pm # L16 .
Saya akan merekomendasikan menggunakan FusionInventory sendiri untuk mendapatkan informasi ini, daripada menerapkan kembali skrip Anda sendiri dengan logika ini, karena komunitas mereka akan menjaga fungsionalitas ini mutakhir. Anda bisa menggunakan agen itu sendiri (menghasilkan file XML / JSON yang mudah diurai) atau memasangkannya dengan solusi yang lebih luas untuk mengelola mesin di jaringan Anda seperti GLPI atau Rudder , tergantung pada kebutuhan Anda.