Đôi khi các tập lệnh của bạn cần hành xử khác nhau trên các Linux khác nhau. Làm cách nào để xác định phiên bản Linux nào mà tập lệnh đang chạy?
Đôi khi các tập lệnh của bạn cần hành xử khác nhau trên các Linux khác nhau. Làm cách nào để xác định phiên bản Linux nào mà tập lệnh đang chạy?
Câu trả lời:
Đừng thử và đưa ra các giả định dựa trên bản phân phối như những gì bạn có thể và không thể làm, vì cách đó là sự điên rồ (xem thêm "Phát hiện tác nhân người dùng"). Thay vào đó, hãy phát hiện xem những gì bạn muốn làm được hỗ trợ hay không và cách thực hiện bằng bất kỳ lệnh hoặc vị trí tệp nào bạn muốn sử dụng.
Ví dụ: nếu bạn muốn cài đặt gói, bạn có thể phát hiện xem bạn đang sử dụng hệ thống giống Debian hay hệ thống giống RedHat bằng cách kiểm tra sự tồn tại của dpkg hoặc vòng / phút (trước tiên hãy kiểm tra dpkg, vì máy Debian có thể có lệnh vòng / phút trên chúng ...). Đưa ra quyết định của bạn về những việc cần làm dựa trên điều đó, không chỉ dựa trên việc đó là hệ thống Debian hay RedHat. Bằng cách đó, bạn sẽ tự động hỗ trợ mọi phân phối phái sinh mà bạn không lập trình rõ ràng. Ồ, và nếu gói của bạn yêu cầu các phụ thuộc cụ thể, thì hãy kiểm tra các phân phối đó và cho người dùng biết họ đang thiếu gì.
Một ví dụ khác là lo lắng với các giao diện mạng. Tìm ra những việc cần làm dựa trên việc có tập tin / etc / network / giao diện hoặc thư mục / etc / sysconfig / network-scripts và đi từ đó.
Vâng, đó là công việc nhiều hơn, nhưng trừ khi bạn muốn làm lại tất cả các lỗi mà các nhà phát triển web đã mắc phải trong thập kỷ qua hoặc hơn, bạn sẽ thực hiện theo cách thông minh ngay từ đầu.
Không có cách phân phối chéo. Tuy nhiên:
- Redhat và bạn bè: Kiểm tra
/etc/redhat-release
, kiểm tra nội dung- Debian: Kiểm tra
/etc/debian_version
, kiểm tra nội dung- Mandriva và bạn bè: Kiểm tra
/etc/version
, kiểm tra nội dung- Slackware: Kiểm tra
/etc/slackware-version
, kiểm tra nội dung
V.v. Nói chung, kiểm tra /etc/*-release
và /etc/*-version
.
Chỉnh sửa: Tìm thấy một tập lệnh bash cũ (hơn 1 năm) của tôi nằm xung quanh rằng tôi phải ghép lại với nhau trong nhiều năm (nó có một bản ghi CVS ấn tượng trở lại sau 6 năm.) Nó có thể không hoạt động đúng như hiện tại và tôi có thể Sẽ không bị làm phiền khi tìm các bản phân phối đã cài đặt để kiểm tra, nhưng nó sẽ cung cấp cho bạn một điểm khởi đầu tốt. Nó hoạt động tốt trên CentOS, Fedora và Gentoo. gyaresu đã thử nghiệm nó thành công trên 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
}
Lưu ý rằng điều này có lẽ sẽ chỉ hoạt động chính xác trong Bash. Bạn có thể viết lại nó cho các shell khác.
Điều đó đang được nói, bạn có thể muốn kiểm tra các tính năng, không phải cho các bản phân phối. Tôi không sử dụng nó nữa đơn giản vì nó trở thành gánh nặng bảo trì. Thật dễ dàng hơn để dựa vào các công cụ và giải pháp phân phối chéo.
Về mặt khái niệm, những gì nó làm là, theo thứ tự:
- Kéo vào một loại tệp "chức năng init script phổ biến" đã biết. Đó là phân phối cụ thể. Nếu nó không tồn tại, bỏ qua kiểm tra phân phối tiếp theo.
- Kiểm tra sự tồn tại của một chức năng cụ thể, đã biết tồn tại, thường được sử dụng và không có khả năng được đổi tên từ tập lệnh cốt lõi đó. Chúng tôi làm điều đó bằng cách sử dụng
type
nội dung Bash.type -t
trả vềfunction
nếu biểu tượng đó là một hàm. Chúng tôi trả trướczz
cho đầu ra từtype -t 2>/dev/null
vì nếu tên không được xác định, chuỗi đầu ra sẽ trống và chúng tôi sẽ gặp lỗi cú pháp về một bàn tay trái bị thiếu cho==
toán tử. Nếu tên chúng tôi vừa kiểm tra không phải là một hàm, hãy bỏ qua kiểm tra phân phối tiếp theo, nếu không chúng tôi đã tìm thấy loại phân phối.- Cuối cùng, lặp lại kiểu phân phối để có thể dễ dàng sử dụng đầu ra hàm trong trường hợp .. khối esac.
Chỉnh sửa trong trường hợp bạn đang cố chạy tập lệnh này dưới dạng tập lệnh thẳng: Tập lệnh này được cho là có nguồn gốc hoặc được bao gồm từ các tập lệnh khác. Nó không tự xuất ra bất cứ thứ gì nếu bạn chạy như cũ. Để kiểm tra nó, nguồn nó và sau đó gọi hàm, ví dụ:
source /path/to/this/script.sh
get_distribution_type
tại dấu nhắc bash.
Chỉnh sửa: Xin lưu ý rằng tập lệnh này không yêu cầu quyền root. Tôi khuyên bạn không nên chạy nó như root. Không nên làm hại bất cứ điều gì, nhưng không có nhu cầu.
Tìm thấy một liên kết đến một bài đăng danh sách gửi thư có liên quan trong nhật ký CVS. Nên hữu ích trong việc mở gói spaghetti init script.
Bạn có thể tìm phiên bản kernel bằng cách chạy uname -a
, việc tìm phiên bản distro phụ thuộc vào distro.
Trên Ubuntu và một số HĐH khác, bạn có thể chạy lsb_release -a
hoặc đọc / etc / lsb_release
Debian lưu trữ phiên bản trong / etc / debian_version
Hầu hết các distro đều có một phương pháp duy nhất để xác định phân phối cụ thể.
Ví dụ:
Redhat (And derivatives): /etc/redhat-release
SUSE: /etc/SUSE-release
Có một tiêu chuẩn ngoài kia được gọi là Cơ sở Tiêu chuẩn Linux hoặc LSB . Nó xác định rằng cần có một tệp có tên / etc / lsb-release hoặc một chương trình có tên lsb_release sẽ phản hồi lại thông tin về bản phân phối linux của bạn.
lsb_release -a
lsb_release
không tồn tại trên CentOS 6.
python -c 'import platform ; print platform.dist()[0]'
mã: http://hg.python.org/cpython/file/2.7/Lib/pl platform.py
python -c 'import platform; print(platform.dist()[0])'
, bởi vì cách đó nó cũng hoạt động nếu con trăn bình thường mặc định là python3.
Ngoài các câu trả lời khác: Nếu bạn chỉ muốn phân tích một tệp, hầu hết các bản phân phối cá nhân hóa thông tin đăng nhập tty qua / etc / vấn đề, vd:
Chào mừng bạn đến với SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l).
Và vâng tôi biết nó không tối ưu. :)
Tất cả bạn cần làm là gõ uname -a
vào vỏ yêu thích của bạn. Điều đó sẽ in ra tên và phiên bản kernel.
Tôi đồng tình với Mark, Adam và Mihai (không thể bỏ phiếu do không đủ uy tín). Các giải pháp dựa trên LSB và FHS tương đối của nó sẽ hoạt động với hầu hết các bản phân phối và có khả năng sẽ tiếp tục hoạt động trong tương lai. LSB và FHS là bạn của bạn.
Phiên bản của linux là một câu hỏi khó. Nếu chúng ta nhìn vào nó một cách hẹp hòi, chúng ta có phiên bản kernel mà bạn có thể có với " uname -r
". Phiên bản phân phối chủ yếu là không phù hợp. Một số bản phân phối tốt hơn (bản phân phối doanh nghiệp như Redhat Enterprise Linux). Các bản phân phối khác như Gentoo về cơ bản là các mục tiêu di chuyển không có phiên bản hợp lý nào cả. Nếu bạn cần làm mọi thứ dựa trên phiên bản, hãy xem các thành phần chính có liên quan đến bạ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...
Bạn cũng có thể kiểm tra menu Grub, thường cung cấp cho bạn một loạt các thông tin phân phối / phiên bản :-)
FusionInventory là một công cụ kiểm kê nhẹ đa nền tảng có thể lấy thông tin này trên nhiều bản phát hành Linux mà còn trên BSD, Windows, MacOS X và các thông báo khác.
Nếu có sẵn, họ sử dụng lsb_release
(như đã đề cập một vài lần ở trên), nhưng nếu không, họ có một danh sách các tệp và biểu thức thông thường rất hữu ích để kiểm tra tên và phiên bản phân phối: https://github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / FusionInventory / Tác nhân / Nhiệm vụ / Hàng tồn kho / Đầu vào / Linux / Phân phối / NonLSB.pm # L16 .
Tôi khuyên bạn nên sử dụng chính FusionInventory để có được thông tin này, thay vì thực hiện lại các tập lệnh của riêng bạn với logic này, vì cộng đồng của họ sẽ duy trì chức năng này được cập nhật. Bạn có thể tự mình sử dụng tác nhân (nó tạo ra tệp XML / JSON dễ phân tích) hoặc kết hợp nó với một giải pháp rộng hơn để quản lý các máy trong mạng của bạn như GLPI hoặc Rudder , tùy theo nhu cầu của bạn.