บางครั้งสคริปต์ของคุณจำเป็นต้องทำงานแตกต่างกันไปใน Linux ที่แตกต่างกัน ฉันจะทราบได้อย่างไรว่าสคริปต์รุ่นใดของ Linux กำลังทำงานอยู่
บางครั้งสคริปต์ของคุณจำเป็นต้องทำงานแตกต่างกันไปใน Linux ที่แตกต่างกัน ฉันจะทราบได้อย่างไรว่าสคริปต์รุ่นใดของ Linux กำลังทำงานอยู่
คำตอบ:
อย่าพยายามตั้งสมมติฐานบนพื้นฐานของ distro ว่าคุณสามารถและไม่สามารถทำได้เพราะวิธีนั้นเป็นเรื่องบ้าคลั่ง (ดู "การตรวจจับตัวแทนผู้ใช้") ตรวจสอบว่าได้รับการสนับสนุนหรือไม่และตรวจสอบว่าคำสั่งหรือตำแหน่งไฟล์ใดที่คุณต้องการใช้
ตัวอย่างเช่นหากคุณต้องการติดตั้งแพคเกจคุณสามารถตรวจสอบว่าคุณอยู่ในระบบที่คล้าย Debian หรือระบบ RedHat-like โดยตรวจสอบการมีอยู่ของ dpkg หรือ rpm (ตรวจสอบ dpkg ก่อนเพราะเครื่อง Debian สามารถมี คำสั่ง rpm ที่พวกเขา ... ) ตัดสินใจว่าจะทำอะไรตามนั้นไม่ใช่แค่ว่ามันเป็นระบบ Debian หรือ RedHat ด้วยวิธีนี้คุณจะสนับสนุน distros อนุพันธ์โดยอัตโนมัติที่คุณไม่ได้ตั้งโปรแกรมไว้อย่างชัดเจนโอ้และหากแพ็คเกจของคุณต้องการการอ้างอิงที่เฉพาะเจาะจงให้ทำการทดสอบสิ่งเหล่านั้นด้วยและแจ้งให้ผู้ใช้ทราบว่าพวกเขากำลังพลาดอะไรอยู่
อีกตัวอย่างหนึ่งคือเล่นซอกับอินเทอร์เฟซเครือข่าย ทำสิ่งที่ต้องทำโดยพิจารณาว่ามีไฟล์ / etc / network / interfaces หรือไดเร็กทอรี / etc / sysconfig / network-สคริปต์หรือไม่และไปจากที่นั่น
ใช่มันเป็นงานที่มากขึ้น แต่ถ้าคุณไม่ต้องการที่จะทำซ้ำข้อผิดพลาดทั้งหมดที่นักพัฒนาเว็บทำไว้ในช่วงสิบปีที่ผ่านมาหรือมากกว่านั้นคุณจะต้องทำอย่างชาญฉลาดตั้งแต่เริ่มต้น
ไม่มีวิธีการกระจายข้าม อย่างไรก็ตาม:
- 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" ที่รู้จัก สิ่งเหล่านี้เป็นการกระจายเฉพาะ หากไม่มีอยู่ให้ข้ามไปที่การตรวจสอบการแจกจ่ายครั้งถัดไป
- ตรวจสอบการมีอยู่ของฟังก์ชั่นที่เฉพาะเจาะจงเป็นที่รู้จักใช้บ่อยและไม่น่าจะถูกเปลี่ยนชื่อจากคอร์สคริปต์หลัก เราทำเช่นนั้นโดยใช้
type
Bash builtintype -t
ส่งคืนfunction
ถ้าสัญลักษณ์นั้นเป็นฟังก์ชัน เราzz
ต่อท้ายเอาท์พุทจากtype -t 2>/dev/null
เพราะหากไม่ได้กำหนดชื่อเอาท์พุทสตริงจะว่างเปล่าและเราจะได้รับข้อผิดพลาดทางไวยากรณ์เกี่ยวกับมือซ้ายที่ขาดหายไปกับ==
โอเปอเรเตอร์ หากชื่อที่เราเพิ่งตรวจสอบไม่ใช่ฟังก์ชันให้ข้ามไปที่การตรวจสอบการแจกจ่ายครั้งถัดไปมิฉะนั้นเราจะพบประเภทการแจกจ่าย- ในที่สุด echo ประเภทการกระจายเพื่อให้ฟังก์ชั่นเอาท์พุทสามารถใช้งานได้อย่างง่ายดายใน ..
แก้ไขในกรณีที่คุณพยายามเรียกใช้งานเป็นสคริปต์แบบตรง: สคริปต์นี้ควรจะได้รับแหล่งที่มาหรือรวมอยู่ในสคริปต์อื่น ๆ มันจะไม่ส่งออกอะไรด้วยตัวเองถ้าคุณเรียกใช้มันเป็น - เป็น เพื่อทดสอบให้แหล่งที่มาแล้วเรียกใช้ฟังก์ชันเช่น:
source /path/to/this/script.sh
get_distribution_type
ที่พรอมต์ทุบตี
แก้ไข: โปรดทราบว่าสคริปต์นี้ไม่ต้องการสิทธิ์พิเศษ ฉันอยากให้คุณไม่เรียกใช้มันในฐานะที่เป็นราก ไม่ควรทำอันตรายอะไร แต่ไม่จำเป็น
พบลิงค์ไปยังรายการจดหมายข่าวที่เกี่ยวข้องในบันทึก CVS ควรมีประโยชน์ในการเปิดสปาเก็ตต์สคริปต์เริ่มต้น
คุณสามารถค้นหารุ่นเคอร์เนลได้โดยการเรียกใช้uname -a
การค้นหาเวอร์ชัน distro นั้นขึ้นอยู่กับ distro
บน Ubuntu และระบบปฏิบัติการอื่น ๆ คุณสามารถเรียกใช้lsb_release -a
หรืออ่าน / etc / lsb_release
Debian เก็บรุ่นไว้ใน / etc / debian_version
ดิสทริบิวชันส่วนใหญ่มีวิธีการเฉพาะในการกำหนดการจำหน่ายเฉพาะ
ตัวอย่างเช่น:
Redhat (And derivatives): /etc/redhat-release
SUSE: /etc/SUSE-release
มีมาตรฐานออกมีที่รู้จักในฐานะเป็นลินุกซ์ฐานมาตรฐานหรือLSB กำหนดว่าควรมีไฟล์ชื่อ / etc / lsb-release หรือโปรแกรมชื่อ lsb_release ที่จะสะท้อนข้อมูลเกี่ยวกับลินุกซ์ distro ของคุณ
lsb_release -a
lsb_release
ไม่มีอยู่ใน CentOS 6
python -c 'import platform ; print platform.dist()[0]'
python -c 'import platform; print(platform.dist()[0])'
เพราะวิธีนี้ยังใช้งานได้ถ้า python ปกติเป็น python3
นอกเหนือจากคำตอบอื่น ๆ : หากคุณต้องการแยกไฟล์หนึ่งไฟล์ distros ส่วนใหญ่จะปรับแต่งล็อกอิน tty เป็นส่วนตัวผ่าน / etc / ปัญหาเช่น:
ยินดีต้อนรับสู่ SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l)
และใช่ฉันรู้ว่ามันแย่มาก :)
facterเป็นเครื่องมือที่มีประโยชน์สำหรับการค้นพบประเภทนี้ถึงแม้ว่ามันอาจใช้วิธีการบางอย่างที่มีรายละเอียดด้านบนและต้องใช้ Ruby
สิ่งที่คุณต้องทำคือพิมพ์uname -a
ที่เชลล์ที่คุณชื่นชอบ ที่จะพิมพ์ชื่อเคอร์เนลและเวอร์ชั่น
ฉันพบว่าใช้งานได้cat /etc/*release*
เกือบทุกครั้ง
ฉันเห็นด้วยกับ Mark, Adam และ Mihai (ไม่สามารถลงคะแนนได้เนื่องจากชื่อเสียงไม่เพียงพอ) โซลูชันที่ใช้ LSB และFHS ที่เกี่ยวข้องจะทำงานร่วมกับการแจกจ่ายส่วนใหญ่และมีแนวโน้มที่จะทำงานต่อไปในอนาคต LSB และ FHS เป็นเพื่อนของคุณ
คุณสามารถรับรุ่นได้ด้วย
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
รุ่นของ 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...
คุณสามารถตรวจสอบเมนู Grub ได้โดยปกติจะให้ข้อมูล distro / version :-)
FusionInventoryเป็นเครื่องมือสินค้าคงคลังแบบข้ามแพลตฟอร์มที่สามารถรับข้อมูลนี้จาก distros Linux จำนวนมาก แต่ยังรวมถึง BSD, Windows, MacOS X และ unices อื่น ๆ
หากมีให้ใช้พวกเขาใช้lsb_release
(ดังกล่าวข้างต้นสองสามครั้ง) แต่ถ้าไม่มีพวกเขาจะมีรายการไฟล์ที่มีประโยชน์มากและนิพจน์ทั่วไปเพื่อตรวจสอบชื่อและเวอร์ชั่นของ distro: https://github.com/fusinv/fusioninventory-agent/ หยด
ฉันขอแนะนำให้ใช้ FusionInventory เพื่อรับข้อมูลนี้แทนที่จะใช้สคริปต์ของคุณเองด้วยตรรกะนี้เนื่องจากชุมชนของพวกเขาจะรักษาฟังก์ชันการทำงานนี้ให้ทันสมัยอยู่เสมอ คุณสามารถใช้ตัวแทนด้วยตัวของมันเอง (มันส่งออกไฟล์ XML / JSON ซึ่งง่ายต่อการแยกวิเคราะห์) หรือจับคู่กับโซลูชั่นที่กว้างขึ้นเพื่อจัดการเครื่องในเครือข่ายของคุณเช่นGLPIหรือRudderขึ้นอยู่กับความต้องการของคุณ