วิธีการตรวจสอบระบบปฏิบัติการจากสคริปต์ทุบตี?


525

ฉันต้องการเก็บไฟล์ของฉัน.bashrcและ.bash_loginไฟล์ต่าง ๆ ไว้ในการควบคุมเวอร์ชันเพื่อให้สามารถใช้งานได้ระหว่างคอมพิวเตอร์ทุกเครื่องที่ฉันใช้ ปัญหาคือฉันมีนามแฝงเฉพาะของระบบปฏิบัติการบางตัวดังนั้นฉันจึงหาวิธีที่จะตรวจสอบว่าสคริปต์นั้นทำงานบน Mac OS X, Linux หรือCygwinหรือไม่

เป็นวิธีที่เหมาะสมในการตรวจสอบระบบปฏิบัติการในสคริปต์Bashอะไร


1
คุณเคยพิจารณาแบ่งปันการกำหนดค่าของคุณหรือไม่ ผมกำลังมองหาที่จะได้รับชนิดเดียวกันของการติดตั้ง :)
โซริน

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

1
@ dimo414 profilegem ดูเหมือนว่าจะได้รับการย้ายมาที่นี่bitbucket.org/dimo414/profilegem เท่าที่การแชร์ bash configs โดยทั่วไปให้ลองโครงการ dotfiles เหล่านี้: github.com/…
mahemoff

1
@mahemoff ขอบคุณสำหรับลิงก์ที่อัปเดตขออภัยฉันไม่สามารถแก้ไขความคิดเห็นของฉันได้ ฉันยินดีรับข้อเสนอแนะหรือข้อบกพร่องหากคุณกำลังทดลองกับ ProfileGem!
dimo414

อนิจจา BitBucket กำลังปิดการสนับสนุน Mercurial ดังนั้นฉันต้องอัปเดตลิงก์ของฉันอีกครั้ง :( github.com/dimo414/ProfileGemเป็นบ้านใหม่
dimo414

คำตอบ:


521

ฉันคิดว่าสิ่งต่อไปนี้ควรใช้งานได้ ผมไม่แน่ใจว่าเกี่ยวกับwin32ว่า

if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        # ...
elif [[ "$OSTYPE" == "darwin"* ]]; then
        # Mac OSX
elif [[ "$OSTYPE" == "cygwin" ]]; then
        # POSIX compatibility layer and Linux environment emulation for Windows
elif [[ "$OSTYPE" == "msys" ]]; then
        # Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
elif [[ "$OSTYPE" == "win32" ]]; then
        # I'm not sure this can happen.
elif [[ "$OSTYPE" == "freebsd"* ]]; then
        # ...
else
        # Unknown.
fi

7
สำหรับ Windows คุณจะได้รับmsysGit Bash / msysGit และcygwinCygwin
friederbluemle

1
คำตอบนี้รวมถึงวิธีการตรวจหา Windows เป็นสิ่งที่ดี ฉันยังใช้ Mingw32 และมันก็เกิดขึ้นเป็นmsys
d48

2
น่าสนใจ .. Mac OSX จะยังคงให้ 'ดาร์วิน'
โจนาธานเบลล์

6
สิ่งที่สะดุดฉันขึ้นเมื่อคุณเปลี่ยนความคิดเห็นที่มีคำสั่ง - ;ให้แน่ใจว่าจะจบลงด้วยการที่มี
Vadim Peretokin

1
เมื่อฉันเพิ่มคำสั่งเหมือนที่ฉันได้รับsource somefile ; syntax error near unexpected token elif
oarfish

292

สำหรับ. bashrc ของฉันฉันใช้รหัสต่อไปนี้:

platform='unknown'
unamestr=`uname`
if [[ "$unamestr" == 'Linux' ]]; then
   platform='linux'
elif [[ "$unamestr" == 'FreeBSD' ]]; then
   platform='freebsd'
fi

จากนั้นฉันก็ทำสิ่งต่าง ๆ เช่น:

if [[ $platform == 'linux' ]]; then
   alias ls='ls --color=auto'
elif [[ $platform == 'freebsd' ]]; then
   alias ls='ls -G'
fi

มันน่าเกลียด แต่มันได้ผล คุณสามารถใช้caseแทนifหากคุณต้องการ


6
ทำไมคุณถึงตั้งแพลตฟอร์มจาก unamestr แทนที่จะใช้ unamestr
csexton

80
อย่าใช้ backticks ใช้ไวยากรณ์ที่ใหม่กว่าที่ชัดเจนกว่า: "unamestr = $ (uname)"
ผ่อนคลาย

15
จากภาพรวมอย่างรวดเร็ว backticks อาจมีลักษณะเป็นสตริง
Harrison Powers

29
@ david-winiecki เพราะถ้าคุณต้องการซ้อนคำสั่งเช่น $ (command-1 $ (command-2))
Michael Barton

4
มันจะไม่ดีกว่าที่จะทำ: platform="$(uname | tr '[:upper:]' '[:lower:]')"แล้วจัดการกับกรณีอย่างแน่นอน? ดูเหมือนว่าแปลกที่ฮาร์ดโค้ดพึ่งพาขึ้นอยู่กับผลลัพธ์ที่เฉพาะเจาะจงมาก
แบรนดอนบั

274

bash manpage บอกว่าตัวแปร OSTYPE เก็บชื่อของระบบปฏิบัติการไว้:

OSTYPEตั้งค่าเป็นสตริงที่อธิบายระบบปฏิบัติการที่ bash กำลังทำงานโดยอัตโนมัติ ค่าเริ่มต้นขึ้นอยู่กับระบบ

มันถูกตั้งค่าlinux-gnuที่นี่


5
นอกจากนี้ $ OSTYPE คือ 'darwin9.0' บน mac ของฉัน (Leopard) และ 'cygwin' ภายใต้ Cygwin
dF

5
$ OSTYPE คือ darwin10.0 บน SnowLeopard WTF รุ่นต่อท้ายหรือไม่ หมายความว่าคำสั่งกรณีง่ายจะไม่ทำงาน
mxcl

16
ไม่ใช่เรื่องใหญ่ที่จะลบมันออกไป:os=${OSTYPE//[0-9.]/}
ABach

86
case $OSTYPE in darwin*) echo I am a Mac ;; esac
tripleee

36
@tripleee หรือสำหรับคนที่มีความคุ้นเคยกับไวยากรณ์ "if" มากขึ้น:if [[ $OSTYPE == darwin* ]]; then echo I am a Mac;fi
Rican7

158

$OSTYPE

คุณสามารถใช้$OSTYPEตัวแปรที่กำหนดไว้ล่วงหน้าเช่น:

case "$OSTYPE" in
  solaris*) echo "SOLARIS" ;;
  darwin*)  echo "OSX" ;; 
  linux*)   echo "LINUX" ;;
  bsd*)     echo "BSD" ;;
  msys*)    echo "WINDOWS" ;;
  *)        echo "unknown: $OSTYPE" ;;
esac

อย่างไรก็ตามเชลล์ที่เก่ากว่านั้นไม่รู้จัก (เช่นBourne shell )


uname

อีกวิธีหนึ่งคือการตรวจสอบแพลตฟอร์มตามunameคำสั่ง

ดูสคริปต์ต่อไปนี้ (พร้อมที่จะรวมใน. bashrc):

# Detect the platform (similar to $OSTYPE)
OS="`uname`"
case $OS in
  'Linux')
    OS='Linux'
    alias ls='ls --color=auto'
    ;;
  'FreeBSD')
    OS='FreeBSD'
    alias ls='ls -G'
    ;;
  'WindowsNT')
    OS='Windows'
    ;;
  'Darwin') 
    OS='Mac'
    ;;
  'SunOS')
    OS='Solaris'
    ;;
  'AIX') ;;
  *) ;;
esac

.bashrcคุณสามารถค้นหาตัวอย่างในทางปฏิบัติบางอย่างในของฉัน


นี่คือรุ่นที่คล้ายกันที่ใช้กับTravis CI :

case $(uname | tr '[:upper:]' '[:lower:]') in
  linux*)
    export TRAVIS_OS_NAME=linux
    ;;
  darwin*)
    export TRAVIS_OS_NAME=osx
    ;;
  msys*)
    export TRAVIS_OS_NAME=windows
    ;;
  *)
    export TRAVIS_OS_NAME=notset
    ;;
esac

1
การตรวจสอบ $ OSTYPE ไม่มีสาขาสำหรับ cygwin ซึ่งจะระบุเครื่อง windows การตรวจสอบ uname จะไม่ทำงานอย่างถูกต้องใน cygwin uname ส่งคืน "CYGWIN_NT-10.0" และ MinGW uname ส่งคืน "MINGW64_NT-10.0"
แมตต์เพนนิงตัน

1
alias ls = '/ bin / ls -G' เป็นตัวเลือกที่ปลอดภัยในบริบทของ fags บนระบบปฏิบัติการโปรดดูที่superuser.com/a/1299969/84662
Andrei Neculau

ผมขอแนะนำให้ใช้unameการประชุม, Oracle OSTYPE ==> solaris2.11ได้กลบเกลื่อนและใส่สตริงรุ่นฟรีที่มีของพวกเขา unameทำความสะอาดน้อยและทำงานน้อยลง
จะ

37

การตรวจสอบระบบปฏิบัติการและประเภทของ CPUไม่เป็นเช่นนั้นง่ายที่จะทำportably ฉันมีshสคริปต์ประมาณ 100 บรรทัดที่ใช้งานได้กับแพลตฟอร์ม Unix หลากหลาย: ระบบใด ๆ ที่ฉันใช้มาตั้งแต่ปี 1988

องค์ประกอบที่สำคัญคือ

  • uname -pเป็นประเภทหน่วยประมวลผลแต่โดยปกติจะใช้unknownกับแพลตฟอร์ม Unix ที่ทันสมัย

  • uname -m จะให้ "ชื่อฮาร์ดแวร์เครื่อง" ในระบบ Unix บางระบบ

  • /bin/archถ้ามีอยู่มักจะให้ประเภทของโปรเซสเซอร์

  • uname โดยไม่มีข้อโต้แย้งจะตั้งชื่อระบบปฏิบัติการ

ในที่สุดคุณจะต้องคิดเกี่ยวกับความแตกต่างระหว่างแพลตฟอร์มและความต้องการที่จะทำให้ดีขึ้น ยกตัวอย่างเช่นเพียงเพื่อให้สิ่งที่ง่ายผมปฏิบัติi386ผ่านi686ใด ๆ " Pentium*" และการใด ๆ " AMD*Athlon*" x86ทั้งหมดเป็น

My ~/.profileรันสคริปต์เมื่อเริ่มต้นซึ่งตั้งค่าตัวแปรหนึ่งตัวเป็นสตริงที่ระบุการรวมกันของ CPU และระบบปฏิบัติการ ฉันมีเฉพาะแพลตฟอร์มbin, man, libและincludeไดเรกทอรีที่ได้รับการตั้งค่าขึ้นอยู่กับว่า จากนั้นฉันจะตั้งค่าเรือบรรทุกของตัวแปรสภาพแวดล้อม ตัวอย่างเช่นเชลล์สคริปต์เพื่อฟอร์แมตเมลสามารถโทรได้เช่น$LIB/mailfmtซึ่งเป็นไบนารีที่ปฏิบัติการเฉพาะแพลตฟอร์ม

หากคุณต้องการที่จะตัดมุม , uname -mและธรรมดาunameจะบอกสิ่งที่คุณต้องการที่จะรู้ในหลายแพลตฟอร์ม เพิ่มสิ่งอื่น ๆ เมื่อคุณต้องการ (และใช้caseไม่ซ้อนกันif!)


2
ตามคำสั่ง uname , uname ที่ไม่มีพารามิเตอร์จะเทียบเท่ากับการใช้พารามิเตอร์ "-s": "-s แสดงชื่อระบบแฟล็กนี้เปิดโดยค่าเริ่มต้น" หากต้องการระบุอย่างชัดเจนสามารถใช้ "uname -s" แทน "uname" (อธิบายเพิ่มเติมในคำตอบของ 'ความช่วยเหลือในการส่งออกเชลล์' )
Peter Mortensen

คุณมีลิงค์ไปยัง git git หรือ pastebin ด้วยสคริปต์ 100 ตัวนี้สำหรับการตรวจสอบระบบปฏิบัติการและสถาปัตยกรรมโปรเซสเซอร์หรือไม่?
Andrew De Andrade

4
@AndrewDeAndrade ฉันละอายใจที่จะเปิดเผยรหัสนี้สู่สาธารณะ pastebin.com/J66Lj6wf
Norman Ramsey

แล้วไงuname -sล่ะ
Alexander Mills

35

ฉันแนะนำให้ใช้รหัสทุบตีที่สมบูรณ์นี้

lowercase(){
    echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
}

OS=`lowercase \`uname\``
KERNEL=`uname -r`
MACH=`uname -m`

if [ "{$OS}" == "windowsnt" ]; then
    OS=windows
elif [ "{$OS}" == "darwin" ]; then
    OS=mac
else
    OS=`uname`
    if [ "${OS}" = "SunOS" ] ; then
        OS=Solaris
        ARCH=`uname -p`
        OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
    elif [ "${OS}" = "AIX" ] ; then
        OSSTR="${OS} `oslevel` (`oslevel -r`)"
    elif [ "${OS}" = "Linux" ] ; then
        if [ -f /etc/redhat-release ] ; then
            DistroBasedOn='RedHat'
            DIST=`cat /etc/redhat-release |sed s/\ release.*//`
            PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
            REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
        elif [ -f /etc/SuSE-release ] ; then
            DistroBasedOn='SuSe'
            PSUEDONAME=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
            REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
        elif [ -f /etc/mandrake-release ] ; then
            DistroBasedOn='Mandrake'
            PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
            REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
        elif [ -f /etc/debian_version ] ; then
            DistroBasedOn='Debian'
            DIST=`cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F=  '{ print $2 }'`
            PSUEDONAME=`cat /etc/lsb-release | grep '^DISTRIB_CODENAME' | awk -F=  '{ print $2 }'`
            REV=`cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F=  '{ print $2 }'`
        fi
        if [ -f /etc/UnitedLinux-release ] ; then
            DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
        fi
        OS=`lowercase $OS`
        DistroBasedOn=`lowercase $DistroBasedOn`
        readonly OS
        readonly DIST
        readonly DistroBasedOn
        readonly PSUEDONAME
        readonly REV
        readonly KERNEL
        readonly MACH
    fi

fi

ตัวอย่างตัวอย่างเพิ่มเติมได้ที่นี่: https://github.com/coto/server-easy-install/blob/master/lib/core.sh


1
คุณออกจากฟังก์ชั่นตัวพิมพ์เล็กฉันอัพเดตคำตอบให้คุณ
Robin Clowers

1
เมื่อคุณรู้ว่ามันคือลีนุกซ์ถ้าคุณแค่เดินไปรอบ ๆ (ไม่พยายามหาคำตอบโดยอัตโนมัติ) ดูเหมือนว่าการย้ายที่ง่ายที่สุดคือการls /etcมองหา "blah-release" - สิ่งใด ๆ ที่เป็น blah นั่นคือ Linux OS - CentOS, Ubuntu ฯลฯ
Chris Moschini

1
ฉันแก้ไขเพราะการอ้างอิงถึงตัวแปร OS บางตัวถูกเขียนเป็น "{$ OS}" ฉันเปลี่ยนพวกเขาเป็น "$ {OS}" นั่นคือวิธีที่ถูกต้องฉันทดสอบมัน
bazz

คุณจะพิจารณาเพิ่ม "echo $ {OS}" ที่ส่วนท้ายสุดของสคริปต์หรือไม่
Oleg Kokorin

10

ในทุบตีใช้$OSTYPEและ$HOSTTYPEเป็นเอกสาร; นี่คือสิ่งที่ฉันทำ หากนั่นยังไม่เพียงพอและหากแม้unameหรือuname -a(หรือตัวเลือกที่เหมาะสมอื่น ๆ ) ไม่ได้ให้ข้อมูลเพียงพอก็จะมีสคริปต์config.guessจากโครงการ GNU อยู่เสมอเพื่อจุดประสงค์นี้


10

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

วิธีแก้ปัญหาหนึ่งดังกล่าวจะเป็นการตรวจสอบง่าย ๆ เช่น:

if [[ "$OSTYPE" =~ ^darwin ]]; then

ซึ่งมีประโยชน์เพิ่มเติมในการจับคู่ดาร์วินเวอร์ชันใด ๆ แม้จะมีคำต่อท้ายเป็นเวอร์ชันก็ตาม วิธีนี้ใช้ได้กับรูปแบบใดก็ได้ที่Linuxอาจคาดหวัง

คุณสามารถดูตัวอย่างเพิ่มเติมได้จาก dotfiles ของฉันที่นี่


9

ลองใช้ "uname" ตัวอย่างเช่นใน Linux: "uname -a"

ตามหน้าคู่มือ uname สอดคล้องกับ SVr4 และ POSIX ดังนั้นจึงควรมีใน Mac OS X และCygwinด้วย แต่ฉันไม่สามารถยืนยันได้

BTW: $ OSTYPE ตั้งไว้linux-gnuที่นี่ด้วย :)


หากไม่มีพารามิเตอร์ให้ uname พิมพ์ 'Darwin' บน Mac OS X (เสือดาว) ด้วย - มันพิมพ์ข้อมูลพิเศษมากมาย (เวอร์ชั่นเคอร์เนล, สถาปัตยกรรมและอย่างอื่นที่ฉันไม่สามารถถอดรหัสได้) ฉันไม่สามารถทดสอบ cygwin
David Rodríguez - dribeas

8

ฉันเขียนน้ำตาลเหล่านี้ใน.bashrc:

if_os () { [[ $OSTYPE == *$1* ]]; }
if_nix () { 
    case "$OSTYPE" in
        *linux*|*hurd*|*msys*|*cygwin*|*sua*|*interix*) sys="gnu";;
        *bsd*|*darwin*) sys="bsd";;
        *sunos*|*solaris*|*indiana*|*illumos*|*smartos*) sys="sun";;
    esac
    [[ "${sys}" == "$1" ]];
}

ดังนั้นฉันสามารถทำสิ่งที่ชอบ:

if_nix gnu && alias ls='ls --color=auto' && export LS_COLORS="..."
if_nix bsd && export CLICOLORS=on && export LSCOLORS="..."
if_os linux && alias psg="ps -FA | grep" #alternative to pgrep
if_nix bsd && alias psg="ps -alwx | grep -i" #alternative to pgrep
if_os darwin && alias finder="open -R"

BTW, 9 บรรทัดนี้ทำงานกับ Bash ใดก็ได้ที่ทำงานบนเกือบทุกอย่าง ไม่มี shellouts และใช้งานได้กับ. bashrc ส่วนบุคคลเกือบทุกสไตล์ (ต้นไม้ใหญ่ซ้อนกันในกรณี / กรณีหรือนามแฝงสุ่มจำนวนมาก) IMO เต้นกางเกงออกทุกคำตอบข้างบน
kfix

จนถึงตอนนี้ใกล้จะเสร็จสมบูรณ์สำหรับการรวม Cygwin และ BSD อื่น ๆ (โดยทั่วไปการรวบรวม * NIX ยอดนิยม)
HidekiAI

สมบูรณ์สำหรับ userlands ที่เกี่ยวข้องในวันนี้และรัน Bash AIX / HP-UX / IRIX / OpenVMS ผู้ใช้สามารถพูดสอด. ของ Windows ระบบย่อยใหม่สำหรับลินุกซ์วิ่งหุ้น amd64 Ubuntu ติดตั้งดังนั้นจึงควรกลับจริงสำหรับทั้ง &if_nix gnu if_os linux
kfix

1
@kfix ใช่ที่เหมาะสมชนะ 10 ทุบตีระบบย่อยเอาท์พุท "ลินุกซ์ GNU" echo $OSTYPEสำหรับ ในการตรวจสอบระบบย่อย win 10 bash โดยเฉพาะทางออกเดียวที่ฉันพบคือการตรวจสอบ "Microsoft" ใน/proc/sys/kernel/osrelease
Jpnh


7

ฉันเขียนไลบรารี Bash ส่วนตัวและกรอบการเขียนสคริปต์ที่ใช้GNU shtoolเพื่อทำการตรวจจับแพลตฟอร์มที่ค่อนข้างแม่นยำ

GNU shtool เป็นชุดสคริปต์แบบพกพาที่ประกอบด้วยคำสั่ง 'แพลตฟอร์ม shtool' ที่มีประโยชน์อื่น ๆ นี่คือผลลัพธ์ของ:

shtool platform -v -F "%sc (%ac) %st (%at) %sp (%ap)"

บนเครื่องที่แตกต่างกัน:

Mac OS X Leopard: 
    4.4BSD/Mach3.0 (iX86) Apple Darwin 9.6.0 (i386) Apple Mac OS X 10.5.6 (iX86)

Ubuntu Jaunty server:
    LSB (iX86) GNU/Linux 2.9/2.6 (i686) Ubuntu 9.04 (iX86)

Debian Lenny:
    LSB (iX86) GNU/Linux 2.7/2.6 (i686) Debian GNU/Linux 5.0 (iX86)

สิ่งนี้ให้ผลลัพธ์ที่น่าพึงพอใจอย่างที่คุณเห็น GNU shtool ค่อนข้างช้าดังนั้นฉันจึงจัดเก็บและอัปเดตการระบุแพลตฟอร์มในไฟล์บนระบบที่สคริปต์ของฉันเรียกใช้ มันเป็นเฟรมเวิร์กของฉันดังนั้นจึงเหมาะกับฉัน แต่ระยะทางของคุณอาจแตกต่างกันไป

ตอนนี้คุณจะต้องหาวิธีที่จะบรรจุ shtool กับสคริปต์ของคุณ แต่มันไม่ใช่การออกกำลังกายที่ยากนัก คุณสามารถย้อนกลับไปที่ผลลัพธ์ uname ได้เช่นกัน

แก้ไข:

ฉันพลาดโพสต์ของเท็ดดี้เกี่ยวกับconfig.guess(อย่างใด) สคริปต์เหล่านี้คล้ายกันมาก แต่ไม่เหมือนกัน ฉันใช้ shtool เป็นการส่วนตัวเพื่อประโยชน์อื่น ๆ เช่นกันและมันก็ใช้ได้ดีสำหรับฉัน


7

คุณสามารถใช้สิ่งต่อไปนี้:

OS=$(uname -s)

จากนั้นคุณสามารถใช้ตัวแปร OS ในสคริปต์ของคุณ


คุณสามารถอธิบายได้ว่าuname -sแตกต่างunameอย่างไร
Alexander Mills

@AlexanderMills -s, --kernel-name พิมพ์ชื่อเคอร์เนล
Chetan kapoor

6

ด้านล่างนี้เป็นวิธีการตรวจหาLinux OS ที่ใช้Debian และ RedHat โดยใช้/ etc / lsb-releaseและ/ etc / os-release (ขึ้นอยู่กับรสชาติของ Linux ที่คุณใช้) และดำเนินการอย่างง่ายโดยยึดตาม

#!/bin/bash
set -e

YUM_PACKAGE_NAME="python python-devl python-pip openssl-devel"
DEB_PACKAGE_NAME="python2.7 python-dev python-pip libssl-dev"

 if cat /etc/*release | grep ^NAME | grep CentOS; then
    echo "==============================================="
    echo "Installing packages $YUM_PACKAGE_NAME on CentOS"
    echo "==============================================="
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Red; then
    echo "==============================================="
    echo "Installing packages $YUM_PACKAGE_NAME on RedHat"
    echo "==============================================="
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Fedora; then
    echo "================================================"
    echo "Installing packages $YUM_PACKAGE_NAME on Fedorea"
    echo "================================================"
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Ubuntu; then
    echo "==============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Ubuntu"
    echo "==============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Debian ; then
    echo "==============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Debian"
    echo "==============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Mint ; then
    echo "============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Mint"
    echo "============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Knoppix ; then
    echo "================================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Kanoppix"
    echo "================================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 else
    echo "OS NOT DETECTED, couldn't install package $PACKAGE"
    exit 1;
 fi

exit 0

ตัวอย่างผลลัพธ์สำหรับUbuntu Linux:

delivery@delivery-E5450$ sudo sh detect_os.sh
[sudo] password for delivery: 
NAME="Ubuntu"
===============================================
Installing packages python2.7 python-dev python-pip libssl-dev on Ubuntu
===============================================
Ign http://dl.google.com stable InRelease
Get:1 http://dl.google.com stable Release.gpg [916 B]                          
Get:2 http://dl.google.com stable Release [1.189 B] 
...            

5

นี่ควรจะปลอดภัยที่จะใช้กับ distros ทั้งหมด

$ cat /etc/*release

สิ่งนี้ก่อให้เกิดสิ่งนี้

     DISTRIB_ID=LinuxMint
     DISTRIB_RELEASE=17
     DISTRIB_CODENAME=qiana
     DISTRIB_DESCRIPTION="Linux Mint 17 Qiana"
     NAME="Ubuntu"
     VERSION="14.04.1 LTS, Trusty Tahr"
     ID=ubuntu
     ID_LIKE=debian
     PRETTY_NAME="Ubuntu 14.04.1 LTS"
     VERSION_ID="14.04"
     HOME_URL="http://www.ubuntu.com/"
     SUPPORT_URL="http://help.ubuntu.com/"
     BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

แยก / กำหนดตัวแปรตามที่คุณต้องการ

หมายเหตุ: ในการตั้งค่าบางอย่าง นี่อาจทำให้คุณมีข้อผิดพลาดบางอย่างที่คุณสามารถเพิกเฉยได้

     cat: /etc/upstream-release: Is a directory

หมายเหตุ: ใน CentOS สิ่งนี้จะให้[user@host ~]$ cat /etc/*release CentOS release 6.4 (Final) CentOS release 6.4 (Final) CentOS release 6.4 (Final)
cfstras

ใช่ผลลัพธ์ที่ฉันโพสต์เป็นตัวอย่างจากแล็ปท็อปเครื่องหนึ่งของฉันไม่ใช่เนื้อหาสแตติกที่คุณเห็นทุกที่
RJ

เพียงแค่เสริมว่าจึงไม่มีใครจะคิดว่าผลที่ได้คือมักจะอยู่ในรูปแบบเดียวกัน :)
cfstras

1
+1 ฉันใช้ set -e ที่จุดเริ่มต้นของสคริปต์ (ดังนั้นโซลูชันนี้ไม่ทำงานdoxer.org/linux-shell-centos-debian-ostype ) และโซลูชันอื่น ๆ นั้นไม่เฉพาะ CentOS แต่ฉันพบการอ้างอิงนี้ซึ่งพิสูจน์คำตอบนี้unix.stackexchange.com/a/92212
gihanchanuka

4
ใช้งานไม่ได้กับ Mac:cat: /etc/*release: No such file or directory
eridal

3

ลองนี้:

DISTRO=$(cat /etc/*-release | grep -w NAME | cut -d= -f2 | tr -d '"')
echo "Determined platform: $DISTRO"

ใน macOS ฉันได้รับcat: /etc/*-release: No such file or directory
csexton

@csexton จริงๆฉันได้รับเหมือนกัน: zsh: no matches found: /etc/*release- นี้จะทำงานเฉพาะสำหรับระบบลินุกซ์ผมคิดว่า ...
อเล็กซานเด Nekrasov

คำตอบนี้ใช้ได้กับ Linux เท่านั้นแน่นอน แต่คำตอบอื่น ๆ นั้นสามารถตรวจจับลีนุกซ์ได้เมื่อเทียบกับระบบอื่นเท่านั้น การค้นพบพื้นฐานนี้ไม่ได้ช่วยอะไรเลยในการค้นพบการกระจาย Linux โดยเฉพาะนั้นสำคัญพอ ๆ กับความแตกต่างระหว่าง FreeBSD และดาร์วิน
โทมัส Urban

3

คุณสามารถใช้สิ่งต่อไปนี้ถ้าข้อและขยายตามความจำเป็น:

if [ "${OSTYPE//[0-9.]/}" == "darwin" ]
then
    aminute_ago="-v-1M"
elif  [ "${OSTYPE//[0-9.]/}" == "linux-gnu" ]
then
    aminute_ago="-d \"1 minute ago\""
fi

2

ฉันลองข้อความด้านบนข้าม Linux distros สองสามตัวและพบว่าต่อไปนี้ทำงานได้ดีที่สุดสำหรับฉัน มันเป็นคำตอบสั้น ๆ ที่กระชับและตรงกับคำว่า Bash บน Windows เช่นกัน

OS=$(cat /etc/*release | grep ^NAME | tr -d 'NAME="') #$ echo $OS # Ubuntu

2
ในขณะที่ข้อมูลโค้ดยินดีต้อนรับและอาจให้ความช่วยเหลือบางอย่าง แต่จะปรับปรุงให้ดีขึ้นอย่างมากหากมีคำอธิบายเกี่ยวกับวิธีการและสาเหตุที่แก้ไขปัญหาได้ โปรดจำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตไม่ใช่เพียงแค่คนที่ถามตอนนี้! โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายและระบุข้อ จำกัด และสมมติฐานที่ใช้
Toby Speight

1
ดูเหมือนว่าดีและสั้นสำหรับระบบ Linux ส่วนใหญ่ แต่น่าเสียดายที่จะส่งผลให้เกิดข้อผิดพลาดใน macOS บางทีนี่อาจจะมากกว่านี้ "ตรวจสอบรสชาติการกระจายของลินุกซ์จาก Bash
csexton

1
@csexton OS=$( ([[ -f /etc/*release ]] && cat /etc/*release | grep ^NAME | tr -d 'NAME="') || echo "Unknown" )สิ่งนี้จะใช้งานได้โดยไม่ผิดพลาด
Kuzeko

จริงๆแล้วนี่เป็นวิธีที่ถูกต้อง OS=$( $(compgen -G "/etc/*release" > /dev/null) && cat /etc/*release | grep ^NAME | tr -d 'NAME="') || $( echo "${OSTYPE//[0-9.]/}")
Kuzeko

@ Kuzeko ฉันยังคงได้รับข้อผิดพลาดในการทำงานบน macOS
csexton

1

ฉันมักจะเก็บ. bashrc และ. bash_alias ไว้ในการแชร์ไฟล์ที่ทุกแพลตฟอร์มสามารถเข้าถึงได้ นี่คือวิธีที่ฉันเอาชนะปัญหาใน. bash_alias ของฉัน:

if [[ -f (name of share)/.bash_alias_$(uname) ]]; then
    . (name of share)/.bash_alias_$(uname)
fi

และฉันมีตัวอย่างเช่น. bash_alias_Linux ด้วย:

alias ls='ls --color=auto'

วิธีนี้ฉันแยกรหัสเฉพาะของแพลตฟอร์มและพกพาคุณสามารถทำเช่นเดียวกันกับ. bashrc


1

วิธีนี้จะตรวจสอบknownไฟล์จำนวนมากเพื่อระบุว่า linux distro เป็น Debian หรือ Ubunu หรือไม่แล้วจะใช้ค่าเริ่มต้นเป็น$OSTYPEตัวแปร

os='Uknown'
unamestr="${OSTYPE//[0-9.]/}"
os=$( compgen -G "/etc/*release" > /dev/null  && cat /etc/*release | grep ^NAME | tr -d 'NAME="'  ||  echo "$unamestr")

echo "$os"

-1

การทำสิ่งต่อไปนี้ช่วยตรวจสอบอย่างถูกต้องสำหรับ Ubuntu:

if [[ "$OSTYPE" =~ ^linux ]]; then
    sudo apt-get install <some-package>
fi

4
แล้วระบบลีนุกซ์อื่น ๆ ที่ไม่ใช้ apt-get ล่ะ?
วิลฟ์

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