Làm cách nào để biết phiên bản Linux nào đang chạy?


29

Đô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?


1
Theo phiên bản, bạn có nghĩa là phiên bản kernel? Phân phối gì? Phiên bản distro?
Chris Up nhẫn

2
Tôi chắc chắn jldugger muốn tìm hiểu hệ thống phân phối nào mà hệ thống đang chạy. Không có khả năng tập lệnh sẽ bị ảnh hưởng bởi phiên bản kernel trừ khi nó phụ thuộc vào một số / sys hoặc / Proc thứ - và thậm chí sau đó thường dễ dàng giả định dựa trên phân phối hơn so với kernel.
Mihai Limbăşan

Câu trả lời:


27

Đừ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.


1
(Mở rộng câu trả lời này) Phát hiện tính năng được ưu tiên hơn trong một số trường hợp, nhưng hãy đảm bảo bạn không bao giờ thử và đoán phân phối từ các tính năng bạn phát hiện! Đừng đọc sai câu trả lời và tìm hiểu xem nền tảng có phải là RedHat hay không dựa trên những tập tin nào trong / etc. Nếu bạn thực sự cần tên phân phối, hãy kiểm tra lsb_release (hoặc / etc / redhat-phát hành, v.v.).
Nicholas Wilson

36

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/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 typenội dung Bash. type -ttrả về functionnếu biểu tượng đó là một hàm. Chúng tôi trả trước zzcho đầu ra từ type -t 2>/dev/nullvì 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.


Tôi đã không nhìn vào lý do tại sao nhưng nó lại quay trở lại để nhắc về Debian Lenny (5.0).
Gareth

gyaresu, bạn đã thực sự gọi hàm get_distribution_type chưa? Tôi đã chỉnh sửa bài đăng để làm rõ (xem ở phía dưới.)
Mihai Limbăşan

@gyaresu: Nếu ở trên không phải là vấn đề, bạn có thể thử thay thế log_begin_msg trong phần Debian bằng log_warning_msg và thử lại không? Có thể đã nhận được tên chức năng sai. Trong mọi trường hợp, nó sẽ trả về "không xác định" nếu chức năng đó không bị chặn, nhưng vẫn còn.
Mihai Limbăşan

@Mihai Doh! Lấy làm tiếc. Không đọc đúng kịch bản. Đã sớm, không có cà phê. Tôi xin lỗi. gyaresu @ debian: ~ / bin $ source server_version.sh gyaresu @ debian: ~ / bin $ get_distribution_type debian
Gareth

@gyaresu: Cảm ơn! Điều đó tốt, nên giúp jldugger biết rằng nó cũng hoạt động trên Debian :)
Mihai Limbăşan

17

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 -ahoặc đọc / etc / lsb_release

Debian lưu trữ phiên bản trong / etc / debian_version


+1 cho lsb_release (cũng hoạt động trên các công cụ phái sinh Red Hat nếu gói đúng được cài đặt)
Josh Kelley

chỉ cho mô tả 'lsb_release -ds'.
flickerfly

6

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

Và tất nhiên, lsb_releasekhông tồn tại trên CentOS 6.
Justin


5

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. :)


Nó có thể là tối ưu phụ, nhưng nó ở cùng một nơi.
Brad Gilbert

4

facter là một công cụ hữu ích cho loại khám phá này, mặc dù nó có thể sử dụng một số phương pháp chi tiết ở trên và yêu cầu Ruby.


2

Tất cả bạn cần làm là gõ uname -avào vỏ yêu thích của bạn. Điều đó sẽ in ra tên và phiên bản kernel.


2

Tôi đã thấy rằng cat /etc/*release*hầu như luôn luôn hoạt động.


2

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.


2

Bạn cũng có thể lấy phiên bản bằng cách

cat /proc/version

o / p:

Phiên bản Linux 2.6.17-13mdv (rtp@octopus.mandriva.com) (phiên bản gcc 4.1.2 20070302 (phát hành trước) (4.1.2-1mdv2007.1)) # 1 SMP Thứ Sáu 23 Tháng 3 19:03:31 UTC 2007


1

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...

1

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 :-)


-1

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.


Đây sẽ là một giải pháp tốt nếu nó không có sự phụ thuộc bên ngoài của các mô-đun Perl
Will Sheppard
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.