ฉันจะรู้ได้อย่างไรว่า Linux เวอร์ชันใดที่ใช้งานอยู่


29

บางครั้งสคริปต์ของคุณจำเป็นต้องทำงานแตกต่างกันไปใน Linux ที่แตกต่างกัน ฉันจะทราบได้อย่างไรว่าสคริปต์รุ่นใดของ Linux กำลังทำงานอยู่


1
ตามเวอร์ชั่นคุณหมายถึงเวอร์ชันของเคอร์เนลหรือไม่ การกระจายแบบไหน รุ่น distro หรือไม่
Chris Upchurch

2
ฉันแน่ใจว่า jldugger ต้องการค้นหาตระกูลการแจกจ่ายที่ระบบกำลังทำงานอยู่ มันไม่น่าเป็นไปได้ที่สคริปต์จะได้รับผลกระทบจากเวอร์ชันเคอร์เนลเว้นแต่ว่าจะขึ้นอยู่กับ / sys หรือ / proc บางอย่าง - และถึงแม้ว่าโดยทั่วไปแล้วจะง่ายกว่าที่จะสมมติตามการกระจายมากกว่าในเคอร์เนล
Mihai Limbăşan

คำตอบ:


27

อย่าพยายามตั้งสมมติฐานบนพื้นฐานของ distro ว่าคุณสามารถและไม่สามารถทำได้เพราะวิธีนั้นเป็นเรื่องบ้าคลั่ง (ดู "การตรวจจับตัวแทนผู้ใช้") ตรวจสอบว่าได้รับการสนับสนุนหรือไม่และตรวจสอบว่าคำสั่งหรือตำแหน่งไฟล์ใดที่คุณต้องการใช้

ตัวอย่างเช่นหากคุณต้องการติดตั้งแพคเกจคุณสามารถตรวจสอบว่าคุณอยู่ในระบบที่คล้าย Debian หรือระบบ RedHat-like โดยตรวจสอบการมีอยู่ของ dpkg หรือ rpm (ตรวจสอบ dpkg ก่อนเพราะเครื่อง Debian สามารถมี คำสั่ง rpm ที่พวกเขา ... ) ตัดสินใจว่าจะทำอะไรตามนั้นไม่ใช่แค่ว่ามันเป็นระบบ Debian หรือ RedHat ด้วยวิธีนี้คุณจะสนับสนุน distros อนุพันธ์โดยอัตโนมัติที่คุณไม่ได้ตั้งโปรแกรมไว้อย่างชัดเจนโอ้และหากแพ็คเกจของคุณต้องการการอ้างอิงที่เฉพาะเจาะจงให้ทำการทดสอบสิ่งเหล่านั้นด้วยและแจ้งให้ผู้ใช้ทราบว่าพวกเขากำลังพลาดอะไรอยู่

อีกตัวอย่างหนึ่งคือเล่นซอกับอินเทอร์เฟซเครือข่าย ทำสิ่งที่ต้องทำโดยพิจารณาว่ามีไฟล์ / etc / network / interfaces หรือไดเร็กทอรี / etc / sysconfig / network-สคริปต์หรือไม่และไปจากที่นั่น

ใช่มันเป็นงานที่มากขึ้น แต่ถ้าคุณไม่ต้องการที่จะทำซ้ำข้อผิดพลาดทั้งหมดที่นักพัฒนาเว็บทำไว้ในช่วงสิบปีที่ผ่านมาหรือมากกว่านั้นคุณจะต้องทำอย่างชาญฉลาดตั้งแต่เริ่มต้น


1
(ขยายคำตอบนี้) การตรวจจับคุณสมบัติเป็นที่นิยมในบางสถานการณ์ แต่ให้แน่ใจว่าคุณไม่เคยลองและเดาการกระจายจากคุณสมบัติที่คุณตรวจพบ! อย่าอ่านคำตอบผิดและดูว่าแพลตฟอร์มนั้นเป็น RedHat หรือไม่โดยพิจารณาจากไฟล์ที่อยู่ใน / etc หากคุณต้องการชื่อการแจกจ่ายให้ตรวจสอบ lsb_release (หรือ / etc / redhat-release และอื่น ๆ )
นิโคลัสวิลสัน

36

ไม่มีวิธีการกระจายข้าม อย่างไรก็ตาม:

  • Redhat และผองเพื่อน: ทดสอบ/etc/redhat-releaseตรวจสอบเนื้อหา
  • Debian: ทดสอบ/etc/debian_version, ตรวจสอบเนื้อหา
  • แมนดวาและเพื่อน: ทดสอบ/etc/versionตรวจสอบเนื้อหา
  • Slackware: ทดสอบ/etc/slackware-versionตรวจสอบเนื้อหา

ฯลฯ โดยทั่วไปการตรวจสอบและ/etc/*-release/etc/*-version


แก้ไข: พบสคริปต์ทุบตีเก่าแก่ (1+ ปี) ของฉันซึ่งฉันต้องปูด้วยกันในช่วงหลายปีที่ผ่านมา (มีบันทึก CVS ที่น่าประทับใจย้อนหลัง 6 ปี) มันอาจทำงานไม่ถูกต้องอีกต่อไปตามที่เป็นอยู่และฉันสามารถ ไม่ต้องกังวลกับการหา distros ที่ติดตั้งเพื่อทดสอบ แต่ควรให้จุดเริ่มต้นที่ดีแก่คุณ มันทำงานได้ดีบน CentOS, Fedora และ Gentoo gyaresuทดสอบมันสำเร็จใน 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
}

โปรดทราบว่านี่อาจทำงานได้อย่างถูกต้องใน Bash คุณสามารถเขียนทับเชลล์อื่นได้

อย่างที่กล่าวไว้คุณอาจต้องการทดสอบคุณลักษณะต่างๆไม่ใช่เพื่อการจำหน่าย ฉันไม่ได้ใช้สิ่งนี้อีกต่อไปเพียงเพราะกลายเป็นภาระในการบำรุงรักษา การพึ่งพาเครื่องมือและโซลูชันแบบกระจายข้ามได้ง่ายขึ้น


ตามแนวคิดแล้วมันคืออะไรตามลำดับ:

  • ดึงไฟล์ประเภท "common init function script" ที่รู้จัก สิ่งเหล่านี้เป็นการกระจายเฉพาะ หากไม่มีอยู่ให้ข้ามไปที่การตรวจสอบการแจกจ่ายครั้งถัดไป
  • ตรวจสอบการมีอยู่ของฟังก์ชั่นที่เฉพาะเจาะจงเป็นที่รู้จักใช้บ่อยและไม่น่าจะถูกเปลี่ยนชื่อจากคอร์สคริปต์หลัก เราทำเช่นนั้นโดยใช้typeBash builtin type -tส่งคืนfunctionถ้าสัญลักษณ์นั้นเป็นฟังก์ชัน เราzzต่อท้ายเอาท์พุทจากtype -t 2>/dev/nullเพราะหากไม่ได้กำหนดชื่อเอาท์พุทสตริงจะว่างเปล่าและเราจะได้รับข้อผิดพลาดทางไวยากรณ์เกี่ยวกับมือซ้ายที่ขาดหายไปกับ==โอเปอเรเตอร์ หากชื่อที่เราเพิ่งตรวจสอบไม่ใช่ฟังก์ชันให้ข้ามไปที่การตรวจสอบการแจกจ่ายครั้งถัดไปมิฉะนั้นเราจะพบประเภทการแจกจ่าย
  • ในที่สุด echo ประเภทการกระจายเพื่อให้ฟังก์ชั่นเอาท์พุทสามารถใช้งานได้อย่างง่ายดายใน ..

แก้ไขในกรณีที่คุณพยายามเรียกใช้งานเป็นสคริปต์แบบตรง: สคริปต์นี้ควรจะได้รับแหล่งที่มาหรือรวมอยู่ในสคริปต์อื่น ๆ มันจะไม่ส่งออกอะไรด้วยตัวเองถ้าคุณเรียกใช้มันเป็น - เป็น เพื่อทดสอบให้แหล่งที่มาแล้วเรียกใช้ฟังก์ชันเช่น:

source /path/to/this/script.sh
get_distribution_type

ที่พรอมต์ทุบตี


แก้ไข: โปรดทราบว่าสคริปต์นี้ไม่ต้องการสิทธิ์พิเศษ ฉันอยากให้คุณไม่เรียกใช้มันในฐานะที่เป็นราก ไม่ควรทำอันตรายอะไร แต่ไม่จำเป็น


พบลิงค์ไปยังรายการจดหมายข่าวที่เกี่ยวข้องในบันทึก CVS ควรมีประโยชน์ในการเปิดสปาเก็ตต์สคริปต์เริ่มต้น


ฉันไม่ได้ดูสาเหตุ แต่มันกลับไปพร้อมท์บน Debian Lenny (5.0)
Gareth

แล้ว, คุณเรียกใช้ฟังก์ชัน get_distribution_type จริง ๆ ได้หรือไม่? ฉันได้แก้ไขโพสต์เพื่อชี้แจง (ดูที่ด้านล่าง.)
Mihai Limbăşan

@gyaresu: หากข้างต้นไม่ได้เป็นปัญหาคุณกรุณาลองเปลี่ยน log_begin_msg ในส่วน Debian ด้วย log_warning_msg แล้วลองใหม่ได้ไหม? อาจทำให้ชื่อฟังก์ชันผิด ไม่ว่าในกรณีใดมันควรส่งคืน "ไม่ทราบ" หากฟังก์ชันนั้นไม่ได้รับการรบกวน แต่ยังคงอยู่
Mihai Limbăşan

@Mihai Doh! ขอโทษ อ่านสคริปต์ไม่ถูกต้อง เมื่อเช้านี้ไม่มีกาแฟ ฉันขอโทษ gyaresu @ debian: ~ / bin $ source server_version.sh gyaresu @ debian: ~ / bin $ get_distribution_type debian
Gareth

@gyaresu: ขอบคุณ! ที่ดีจะช่วย jldugger ที่จะรู้ว่าการทำงานใน Debian เช่นกัน :)
หมดเวลาLimbăşan

17

คุณสามารถค้นหารุ่นเคอร์เนลได้โดยการเรียกใช้uname -aการค้นหาเวอร์ชัน distro นั้นขึ้นอยู่กับ distro

บน Ubuntu และระบบปฏิบัติการอื่น ๆ คุณสามารถเรียกใช้lsb_release -aหรืออ่าน / etc / lsb_release

Debian เก็บรุ่นไว้ใน / etc / debian_version


+1 สำหรับ lsb_release (ยังทำงานบน Red Hat อนุพันธ์ถ้าแพคเกจที่เหมาะสมมีการติดตั้ง)
จอชเคลลี่

เพียงแค่คำอธิบาย 'lsb_release -ds'
flickerfly

6

ดิสทริบิวชันส่วนใหญ่มีวิธีการเฉพาะในการกำหนดการจำหน่ายเฉพาะ

ตัวอย่างเช่น:

Redhat (And derivatives): /etc/redhat-release

SUSE: /etc/SUSE-release

มีมาตรฐานออกมีที่รู้จักในฐานะเป็นลินุกซ์ฐานมาตรฐานหรือLSB กำหนดว่าควรมีไฟล์ชื่อ / etc / lsb-release หรือโปรแกรมชื่อ lsb_release ที่จะสะท้อนข้อมูลเกี่ยวกับลินุกซ์ distro ของคุณ

lsb_release -a

และแน่นอนlsb_releaseไม่มีอยู่ใน CentOS 6
Justin


5

นอกเหนือจากคำตอบอื่น ๆ : หากคุณต้องการแยกไฟล์หนึ่งไฟล์ distros ส่วนใหญ่จะปรับแต่งล็อกอิน tty เป็นส่วนตัวผ่าน / etc / ปัญหาเช่น:

ยินดีต้อนรับสู่ SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l)

และใช่ฉันรู้ว่ามันแย่มาก :)


อาจดีที่สุดย่อย แต่อยู่ในสถานที่เดียวกัน
แบรดกิลเบิร์

4

facterเป็นเครื่องมือที่มีประโยชน์สำหรับการค้นพบประเภทนี้ถึงแม้ว่ามันอาจใช้วิธีการบางอย่างที่มีรายละเอียดด้านบนและต้องใช้ Ruby


2

สิ่งที่คุณต้องทำคือพิมพ์uname -aที่เชลล์ที่คุณชื่นชอบ ที่จะพิมพ์ชื่อเคอร์เนลและเวอร์ชั่น



2

ฉันเห็นด้วยกับ Mark, Adam และ Mihai (ไม่สามารถลงคะแนนได้เนื่องจากชื่อเสียงไม่เพียงพอ) โซลูชันที่ใช้ LSB และFHS ที่เกี่ยวข้องจะทำงานร่วมกับการแจกจ่ายส่วนใหญ่และมีแนวโน้มที่จะทำงานต่อไปในอนาคต LSB และ FHS เป็นเพื่อนของคุณ


2

คุณสามารถรับรุ่นได้ด้วย

cat /proc/version

o / p:

รุ่น Linux 2.6.17-13mdv (rtp@octopus.mandriva.com) (รุ่น gcc 4.1.2 20070302 (วางจำหน่ายก่อนวางจำหน่าย) (4.1.2-1mdv2007.1)) # 1 SMP ศุกร์ 23 มีนาคมเวลา 19:03:31 UTC 2007


1

รุ่นของ linux เป็นคำถามที่ยาก ถ้าเราดูที่แคบเรามีรุ่นเคอร์เนลคุณสามารถรับด้วย " uname -r" รุ่นการแจกจ่ายส่วนใหญ่จะไม่เกี่ยวข้อง การแจกแจงบางอย่างดีกว่า (การกระจายขององค์กรเช่น Redhat Enterprise Linux) ดิสทริบิวชันอื่น ๆ เช่น Gentoo นั้นเคลื่อนที่ไปตามเป้าหมายที่ไม่มีเวอร์ชั่นที่สมเหตุสมผลเลย หากคุณต้องการทำสิ่งต่าง ๆ ตามเวอร์ชันให้ดูที่ส่วนประกอบสำคัญที่เกี่ยวข้องกับคุณ:

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

FusionInventoryเป็นเครื่องมือสินค้าคงคลังแบบข้ามแพลตฟอร์มที่สามารถรับข้อมูลนี้จาก distros Linux จำนวนมาก แต่ยังรวมถึง BSD, Windows, MacOS X และ unices อื่น ๆ

หากมีให้ใช้พวกเขาใช้lsb_release(ดังกล่าวข้างต้นสองสามครั้ง) แต่ถ้าไม่มีพวกเขาจะมีรายการไฟล์ที่มีประโยชน์มากและนิพจน์ทั่วไปเพื่อตรวจสอบชื่อและเวอร์ชั่นของ distro: https://github.com/fusinv/fusioninventory-agent/ หยด

ฉันขอแนะนำให้ใช้ FusionInventory เพื่อรับข้อมูลนี้แทนที่จะใช้สคริปต์ของคุณเองด้วยตรรกะนี้เนื่องจากชุมชนของพวกเขาจะรักษาฟังก์ชันการทำงานนี้ให้ทันสมัยอยู่เสมอ คุณสามารถใช้ตัวแทนด้วยตัวของมันเอง (มันส่งออกไฟล์ XML / JSON ซึ่งง่ายต่อการแยกวิเคราะห์) หรือจับคู่กับโซลูชั่นที่กว้างขึ้นเพื่อจัดการเครื่องในเครือข่ายของคุณเช่นGLPIหรือRudderขึ้นอยู่กับความต้องการของคุณ


นี่จะเป็นทางออกที่ดีหากไม่มีการพึ่งพาโมดูล Perl ภายนอก
Will Sheppard
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.