Làm thế nào để phát hiện HĐH từ tập lệnh Bash?


525

Tôi muốn giữ cho tôi .bashrc.bash_logincác tệp trong kiểm soát phiên bản để tôi có thể sử dụng chúng giữa tất cả các máy tính tôi sử dụng. Vấn đề là tôi có một số bí danh cụ thể của hệ điều hành nên tôi đang tìm cách xác định xem tập lệnh có chạy trên Mac OS X, Linux hay Cygwin hay không .

Cách thích hợp để phát hiện hệ điều hành trong tập lệnh Bash là gì?


1
Bạn đã bao giờ xem xét chia sẻ cấu hình của bạn? Tôi đang tìm cách để có được loại thiết lập tương tự :)
sorin

@sorin Tôi biết đó là một nhận xét cũ, nhưng nếu bạn vẫn tò mò, tôi đã xây dựng ProfileGem cho phép bạn định cấu hình môi trường bash có thể cắm cho tất cả các máy của bạn.
dimo414

1
@ dimo414 profilegem dường như đã được chuyển đến đây bitbucket.org/dimo414/profilegem . Theo như chia sẻ cấu hình bash nói chung, hãy thử một số dự án dotfiles này: github.com/,
mahemoff

1
@mahemoff cảm ơn vì liên kết đã cập nhật, xin lỗi tôi không thể chỉnh sửa nhận xét của mình. Tôi hoan nghênh phản hồi hoặc lỗi nếu bạn đang thử nghiệm với ProfileGem!
dimo414

Alas BitBucket đang từ chối hỗ trợ Mercurial, vì vậy tôi phải cập nhật lại liên kết của mình :( github.com/dimo414/ProfileGem là ngôi nhà mới.
dimo414

Câu trả lời:


521

Tôi nghĩ rằng sau đây nên làm việc. Tôi không chắc chắn về win32mặc dù.

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
Trên Windows, bạn sẽ nhận được msysGit Bash / msysGit và cygwincho Cygwin
Friederbluemle

1
Câu trả lời này bao gồm cả cách phát hiện cho Windows là tốt. Tôi cũng đang sử dụng Mingw32 và nó xuất hiện vào lúcmsys
d48

2
Thật thú vị .. Mac OSX vẫn sẽ cho 'darwin'.
jonathanbell

6
Một cái gì đó làm tôi vấp ngã, khi bạn thay thế nhận xét bằng một lệnh - hãy chắc chắn kết thúc bằng ;.
Vadim Peretokin

1
Khi tôi thêm một lệnh như thế source somefile ; , tôi nhận được syntax error near unexpected token elif.
oarfish

292

Đối với .bashrc của tôi, tôi sử dụng mã sau đây:

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

Sau đó, tôi làm một số việc như:

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

Nó xấu, nhưng nó hoạt động. Bạn có thể sử dụng casethay vì ifnếu bạn thích.


6
Tại sao bạn đặt nền tảng từ unamestr, thay vì chỉ sử dụng unamestr?
csexton

80
Không sử dụng backticks, sử dụng cú pháp rõ ràng mới hơn: "unamestr = $ (uname)".
thư giãn

15
Từ cái nhìn nhanh, các backticks có thể giống như một chuỗi.
Harrison Powers

29
@ david-winiecki Bởi vì nếu bạn cần lồng các lệnh, ví dụ $ (lệnh-1 $ (lệnh-2))
Michael Barton

4
Sẽ không tốt hơn nhiều để làm: platform="$(uname | tr '[:upper:]' '[:lower:]')"và sau đó chắc chắn xử lý trong một trường hợp? Nó chỉ có vẻ kỳ lạ khi hardcode một phụ thuộc vào đầu ra rất cụ thể.
Brandon Buck

274

Trang bash nói rằng biến OSTYPE lưu trữ tên của hệ điều hành:

OSTYPETự động đặt thành một chuỗi mô tả hệ điều hành mà bash đang thực thi. Mặc định là phụ thuộc vào hệ thống.

Nó được đặt linux-gnuở đây.


5
Ngoài ra, $ OSTYPE là 'darwin9.0' trên mac của tôi (Leopard) và 'cygwin' dưới Cygwin.
dF.

5
$ OSTYPE là darwin10.0 trên SnowLeopard. WTF với phiên bản được nối thêm? Có nghĩa là một tuyên bố trường hợp đơn giản sẽ không làm việc.
mxcl

16
Nó không phải là một thỏa thuận lớn để loại bỏ nó:os=${OSTYPE//[0-9.]/}
ABach

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

36
@tripleee hoặc cho những người thoải mái hơn với cú pháp "nếu":if [[ $OSTYPE == darwin* ]]; then echo I am a Mac;fi
Rican7

159

$OSTYPE

Bạn chỉ có thể sử dụng $OSTYPEbiến được xác định trước, ví dụ:

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

Tuy nhiên, nó không được nhận ra bởi các vỏ cũ hơn (như vỏ Bourne ).


uname

Một phương pháp khác là phát hiện nền tảng dựa trên unamelệnh.

Xem đoạn mã sau (sẵn sàng để đưa vào .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

Bạn có thể tìm thấy một số ví dụ thực tế trong tôi.bashrc .


Đây là phiên bản tương tự được sử dụng trên 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
Kiểm tra $ OSTYPE thiếu một chi nhánh cho cygwin, sẽ chỉ ra một máy windows. Kiểm tra uname cũng không hoạt động chính xác, trên cygwin uname trả về "CYGWIN_NT-10.0" và trên MinGW uname trả về "MINGW64_NT-10.0".
Matt Pennington

1
alias ls = '/ bin / ls -G' thực sự là tùy chọn an toàn, trong bối cảnh các fags dựa trên hệ điều hành, hãy xem superuser.com/a/1299969/84662
Andrei Neculau

Tôi đề nghị sử dụng uname, Oracle đã quy ước và đặt một chuỗi phiên bản miễn phí với họ OSTYPE ==> solaris2.11. unamelà một chút sạch sẽ và ít việc phải làm.
sẽ

37

Phát hiện hệ điều hành và loại CPU không phải là dễ dàng như vậy để làm portably . Tôi có một shkịch bản gồm khoảng 100 dòng hoạt động trên rất nhiều nền tảng Unix: bất kỳ hệ thống nào tôi đã sử dụng từ năm 1988.

Các yếu tố chính là

  • uname -ploại bộ xử lý nhưng thường là unknowntrên các nền tảng Unix hiện đại.

  • uname -m sẽ cung cấp "tên phần cứng máy" trên một số hệ thống Unix.

  • /bin/arch, nếu nó tồn tại, thường sẽ cung cấp loại bộ xử lý.

  • uname không có đối số sẽ đặt tên cho hệ điều hành.

Cuối cùng, bạn sẽ phải suy nghĩ về sự khác biệt giữa các nền tảng và mức độ bạn muốn tạo ra chúng. Ví dụ, chỉ để giữ cho mọi thứ đơn giản, tôi đối xử với i386qua i686, bất kỳ " Pentium*" và bất kỳ " AMD*Athlon*" tất cả như x86.

My ~/.profilechạy một tập lệnh khi khởi động, đặt một biến thành một chuỗi biểu thị sự kết hợp giữa CPU và hệ điều hành. Tôi có nền tảng cụ thể bin, man, lib, và includethư mục được thiết lập dựa trên đó. Sau đó, tôi đặt một thuyền các biến môi trường. Vì vậy, ví dụ, một kịch bản shell để định dạng lại thư có thể gọi, ví dụ, $LIB/mailfmtđây là một tệp nhị phân thực thi dành riêng cho nền tảng.

Nếu bạn muốn cắt góc , uname -mvà đơn giản unamesẽ cho bạn biết những gì bạn muốn biết trên nhiều nền tảng. Thêm những thứ khác khi bạn cần nó. (Và sử dụng case, không lồng nhau if!)


2
Theo lệnh uname , uname không có tham số tương đương với việc sử dụng tham số "-s": "-s Hiển thị tên hệ thống. Cờ này được bật theo mặc định.". Để rõ ràng, người ta có thể sử dụng "uname -s" thay vì "uname". (Xây dựng phần nào trong câu trả lời cho 'Trợ giúp đầu ra Shell' )
Peter Mortensen

Bạn có liên kết đến một github git hoặc pastebin với tập lệnh 100 này để phát hiện kiến ​​trúc hệ điều hành và bộ xử lý đáng tin cậy không?
Andrew De Andrade

4
@AndrewDeAndrade Tôi xấu hổ khi để lộ mã này ra công chúng. pastebin.com/J66Lj6wf
Norman Ramsey

vậy làm thế nào về uname -s?
Alexander Mills

35

Tôi khuyên bạn nên sử dụng mã bash hoàn chỉnh này

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

ví dụ khác ví dụ ở đây: https://github.com/coto/server-easy-install/blob/master/lib/core.sh


1
Bạn bỏ chức năng viết thường, tôi cập nhật câu trả lời cho bạn.
Robin Clowers 17/212

1
Khi bạn biết đó là Linux, nếu bạn chỉ chọc ngoáy (không cố gắng tự động hóa việc tìm hiểu) thì có vẻ như cách dễ nhất là tìm ls /etcvà phát hành "blah-phát hành" - bất kể đó là hệ điều hành Linux - CentOS, Ubuntu , v.v.
Chris Moschini

1
Tôi đã chỉnh sửa vì một số tham chiếu đến biến OS được viết là "{$ OS}" Tôi đã đổi chúng thành "$ {OS}", đó là cách đúng đắn, tôi đã thử nghiệm nó
bazz

bạn có cân nhắc thêm "echo $ {OS}" vào cuối đoạn script không?
Oleg Kokorin

10

Trong bash, sử dụng $OSTYPE$HOSTTYPE, như tài liệu; đây là những gì tôi làm. Nếu điều đó là không đủ và nếu thậm chí unamehoặc uname -a(hoặc các tùy chọn phù hợp khác) không cung cấp đủ thông tin, luôn tập lệnh config.guess từ dự án GNU, được thực hiện chính xác cho mục đích này.


10

Tôi sẽ đề nghị tránh một số câu trả lời. Đừng quên rằng bạn có thể chọn các hình thức so sánh chuỗi khác, điều này sẽ xóa hầu hết các biến thể hoặc mã xấu được cung cấp.

Một giải pháp như vậy sẽ là một kiểm tra đơn giản, chẳng hạn như:

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

Điều này có thêm lợi ích của việc phù hợp với bất kỳ phiên bản nào của Darwin, mặc dù đó là hậu tố phiên bản. Điều này cũng hoạt động cho bất kỳ biến thể của Linuxmột người có thể mong đợi.

Bạn có thể xem một số ví dụ bổ sung trong dotfiles của tôi ở đây


9

Hãy thử sử dụng "uname". Ví dụ: trong Linux: "uname -a".

Theo trang hướng dẫn, uname phù hợp với SVr4 và POSIX, do đó, nó cũng có sẵn trên Mac OS X và Cygwin , nhưng tôi không thể xác nhận điều đó.

BTW: $ OSTYPE cũng được đặt linux-gnuở đây :)


Không có tham số, uname in 'Darwin' trên Mac OS X (da báo). Với -a nó in ra rất nhiều thông tin bổ sung (phiên bản kernel, kiến ​​trúc và những thứ khác tôi không thể giải mã). Tôi không thể kiểm tra trên cygwin
David Rodríguez - dribeas

8

Tôi đã viết những loại đường này trong .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" ]];
}

Vì vậy, tôi có thể làm những thứ như:

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 dòng này hoạt động trên mọi Bash chạy trên hầu hết mọi thứ. Không có shellouts và hoạt động với hầu hết mọi kiểu .bashrc cá nhân (cây lớn nếu / trường hợp lồng nhau hoặc nhiều bí danh ngẫu nhiên). IMO, đánh bại tất cả các câu trả lời trên nó.
kfix

Cho đến nay, gần nhất để hoàn thành bao gồm Cygwin và BSD khác (về cơ bản là tổng hợp phổ biến * NIX)
HidekiAI

Hoàn thành cho các vùng người dùng có liên quan ngày hôm nay và chạy Bash. Người dùng AIX / HP-UX / IRIX / OpenVMS có thể kết nối. Hệ thống con Windows mới cho Linux chạy bản cài đặt Ubuntu amd64 vì vậy nó sẽ trả về đúng cho cả hai if_nix gnu& if_os linux.
kfix

1
@kfix đúng vậy, hệ thống con win 10 bash xuất ra "linux-gnu" cho echo $OSTYPE. Để phát hiện cụ thể hệ thống con win 10 bash, giải pháp duy nhất tôi tìm thấy là kiểm tra "Microsoft" trong/proc/sys/kernel/osrelease
Jpnh


7

Tôi đã viết một thư viện Bash cá nhân và khung kịch bản sử dụng GNU shtool để thực hiện phát hiện nền tảng khá chính xác.

GNU shtool là một tập lệnh rất di động có chứa, trong số những thứ hữu ích khác, lệnh 'nền tảng shtool'. Đây là đầu ra của:

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

trên một vài máy khác nhau:

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)

Điều này tạo ra kết quả khá khả quan, như bạn có thể thấy. GNU shtool hơi chậm, vì vậy tôi thực sự lưu trữ và cập nhật nhận dạng nền tảng trong một tệp trên hệ thống mà tập lệnh của tôi gọi. Đó là khuôn khổ của tôi, vì vậy nó phù hợp với tôi, nhưng số dặm của bạn có thể thay đổi.

Bây giờ, bạn sẽ phải tìm cách đóng gói shtool với các tập lệnh của mình, nhưng đó không phải là một bài tập khó. Bạn luôn có thể rơi vào đầu ra uname.

BIÊN TẬP:

Tôi đã bỏ lỡ bài viết của Teddy về config.guess(bằng cách nào đó). Đây là những kịch bản rất giống nhau, nhưng không giống nhau. Cá nhân tôi cũng sử dụng shtool cho các mục đích sử dụng khác và nó đã hoạt động khá tốt đối với tôi.


7

Bạn có thể sử dụng như sau:

OS=$(uname -s)

sau đó bạn có thể sử dụng biến hệ điều hành trong tập lệnh của mình.


bạn có thể giải thích như thế nào uname -slà khác nhau uname?
Alexander Mills

@AlexanderMills -s, --kernel-name in tên kernel
Chetan kapoor 13/07/18

6

Bên dưới đây là cách tiếp cận để phát hiện HĐH Linux dựa trên Debian và RedHat bằng cách sử dụng / etc / lsb-phát hành/ etc / os-phát hành (tùy thuộc vào hương vị Linux bạn đang sử dụng) và thực hiện một hành động đơn giản dựa trên nó.

#!/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

Ví dụ đầu ra cho 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

Điều này nên an toàn để sử dụng trên tất cả các distro.

$ cat /etc/*release

Điều này tạo ra một cái gì đó như thế này.

     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/"

Trích xuất / gán cho các biến như bạn muốn

Lưu ý: Trên một số thiết lập. Điều này cũng có thể cung cấp cho bạn một số lỗi mà bạn có thể bỏ qua.

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

Lưu ý: trên CentOS, điều này mang lại[user@host ~]$ cat /etc/*release CentOS release 6.4 (Final) CentOS release 6.4 (Final) CentOS release 6.4 (Final)
cfstras

Có, đầu ra tôi đã đăng là một ví dụ, từ một trong những máy tính xách tay của tôi, không phải nội dung tĩnh mà bạn thấy ở mọi nơi.
RJ

Chỉ cần thêm rằng vì vậy không ai có thể nghĩ rằng kết quả luôn ở dạng tương tự :)
cfstras

1
+1 Tôi đang sử dụng set -e ở đầu tập lệnh (Do đó, giải pháp này không hoạt động doxer.org/linux-shell-centos-debian-ostype ). Và các giải pháp khác không đặc biệt là CentOS. Nhưng tôi đã tìm thấy tài liệu tham khảo này đã chứng minh câu trả lời này unix.stackexchange.com/a/92212
gihanchanuka

4
không hoạt động cho Mac:cat: /etc/*release: No such file or directory
eridal

3

thử cái này:

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

Trên macOS tôi nhận đượccat: /etc/*-release: No such file or directory
csexton

@csexton thực sự, tôi đang nhận được điều tương tự: zsh: no matches found: /etc/*release- điều này sẽ chỉ hoạt động cho các hệ thống linux, tôi cho rằng ...
Alexander Nekrasov

Câu trả lời này chỉ có tác dụng với Linux. Nhưng các câu trả lời khác chỉ có khả năng phát hiện Linux đối lập với các hệ thống khác. Khám phá cơ bản này không giúp ích gì cho việc khám phá phân phối Linux cụ thể là điều cần thiết như phân biệt giữa FreeBSD và Darwin.
Thomas Urban

3

Bạn có thể sử dụng mệnh đề if sau và mở rộng nó khi cần:

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

Tôi đã thử các thông báo trên trên một số bản phân phối Linux và thấy các mục sau đây phù hợp nhất với tôi. Đây là một câu trả lời ngắn gọn, chính xác, ngắn gọn, phù hợp với Bash trên Windows.

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

2
Trong khi đoạn mã này được chào đón và có thể cung cấp một số trợ giúp, nó sẽ là cải thiện rất nhiều nếu nó bao gồm một lời giải thích về cách thứclý do tại sao điều này giải quyết vấn đề. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ là người hỏi bây giờ! Vui lòng chỉnh sửa câu trả lời của bạn để thêm giải thích và đưa ra dấu hiệu về những hạn chế và giả định được áp dụng.
Toby Speight

1
Có vẻ tốt và ngắn gọn cho hầu hết các hệ thống linux, nhưng thật không may, điều này sẽ dẫn đến một lỗi trên macOS. Có lẽ đây là "phát hiện hương vị phân phối linux từ Bash
csexton

1
@csexton OS=$( ([[ -f /etc/*release ]] && cat /etc/*release | grep ^NAME | tr -d 'NAME="') || echo "Unknown" )này sẽ hoạt động mà không ném lỗi.
Kuzeko

Trên thực tế, đây là một cách chính xác OS=$( $(compgen -G "/etc/*release" > /dev/null) && cat /etc/*release | grep ^NAME | tr -d 'NAME="') || $( echo "${OSTYPE//[0-9.]/}")
Kuzeko

@Kuzeko Rất tiếc, tôi vẫn gặp lỗi khi chạy trên macOS.
csexton

1

Tôi có xu hướng giữ .bashrc và .bash_alias của mình trên một tệp chia sẻ mà tất cả các nền tảng có thể truy cập. Đây là cách tôi chinh phục vấn đề trong .bash_alias của mình:

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

Và tôi có ví dụ .bash_alias_Linux với:

alias ls='ls --color=auto'

Bằng cách này, tôi giữ riêng mã nền tảng và mã di động, bạn có thể làm tương tự cho .bashrc


1

Điều này kiểm tra một loạt các knowntệp để xác định nếu bản phân phối linux là Debian hoặc Ubunu, sau đó nó mặc định là $OSTYPEbiến.

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

Làm như sau đã giúp thực hiện kiểm tra chính xác cho Ubuntu:

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

4
Còn các hệ thống Linux khác không sử dụng apt-get thì sao?
Wilf

Ubuntu là một bản phân phối, không phải là một lớp hệ điều hành.
jitter
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.