Bagaimana cara mendeteksi OS dari skrip Bash?

526

Saya ingin menyimpan .bashrcdan .bash_loginfile saya dalam kontrol versi sehingga saya dapat menggunakannya di antara semua komputer yang saya gunakan. Masalahnya adalah saya memiliki beberapa alias khusus OS, jadi saya mencari cara untuk menentukan apakah skrip berjalan pada Mac OS X, Linux atau Cygwin .

Apa cara yang tepat untuk mendeteksi sistem operasi dalam skrip Bash ?

csexton
sumber
1
Pernahkah Anda mempertimbangkan untuk membagikan konfigurasi Anda? Saya sedang mencari untuk mendapatkan jenis yang sama dari pengaturan :)
Sorin
@sorin Saya tahu ini adalah komentar lama, tetapi jika Anda masih penasaran, saya telah membangun ProfileGem yang memungkinkan Anda mengonfigurasi lingkungan bash yang dapat dicolokkan untuk semua mesin Anda.
dimo414
1
@ dimo414 profilegem tampaknya telah dipindahkan ke sini bitbucket.org/dimo414/profilegem . Sejauh berbagi konfigurasi bash secara umum, coba beberapa proyek dotfiles ini: github.com/...
mahemoff
1
@mahemoff terima kasih atas tautan yang diperbarui, maaf saya tidak dapat mengedit komentar saya. Saya akan menyambut umpan balik atau bug jika Anda bereksperimen dengan ProfileGem!
dimo414
Alas BitBucket menolak dukungan Mercurial, jadi saya harus memperbarui tautan lagi :( github.com/dimo414/ProfileGem adalah rumah baru.
dimo414

Jawaban:

522

Saya pikir yang berikut ini harus bekerja. Saya tidak yakin tentang itu 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
Timmmm
sumber
7
Di Windows, Anda akan mendapatkan msysuntuk Git Bash / msysGit, dan cygwinuntuk Cygwin
friederbluemle
1
Jawaban ini termasuk cara mendeteksi untuk Windows adalah baik. Saya juga menggunakan Mingw32 dan muncul sebagaimsys
d48
2
Menarik .. Mac OSX masih akan memberi 'darwin'.
Jonathanbell
6
Sesuatu yang membuat saya tersandung, ketika Anda mengganti komentar dengan perintah - pastikan untuk mengakhiri dengan ;.
Vadim Peretokin
1
Ketika saya menambahkan perintah seperti source somefile ; , saya dapatkan syntax error near unexpected token elif.
oarfish
292

Untuk .bashrc saya, saya menggunakan kode berikut:

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

Kemudian saya melakukan sesuatu seperti:

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

Itu jelek, tapi berhasil. Anda dapat menggunakan casedaripada ifjika Anda inginkan.

Nicolas Martyanoff
sumber
6
Mengapa Anda mengatur platform dari unamestr, bukan hanya menggunakan unamestr?
csexton
80
Jangan gunakan backticks, gunakan sintaks yang lebih jelas lebih baru: "unamestr = $ (uname)".
bersantai
15
Dari pandangan sekilas, backticks bisa menyerupai string.
Harrison Powers
29
@ david-winiecki Karena jika Anda perlu membuat sarang perintah misalnya $ (command-1 $ (command-2))
Michael Barton
4
Bukankah itu jauh lebih baik untuk dilakukan: platform="$(uname | tr '[:upper:]' '[:lower:]')"dan kemudian pasti menangani suatu kasus? Sepertinya aneh untuk hardcode ketergantungan pada output yang sangat spesifik.
Brandon Buck
274

Manual bash mengatakan bahwa variabel OSTYPE menyimpan nama sistem operasi:

OSTYPESecara otomatis diatur ke string yang menjelaskan sistem operasi yang dijalankan bash. Standarnya tergantung pada sistem.

Sudah diatur di linux-gnusini.

Johannes Schaub - litb
sumber
5
Juga, $ OSTYPE adalah 'darwin9.0' di mac saya (Leopard) dan 'cygwin' di bawah Cygwin.
dF.
5
$ OSTYPE adalah darwin10.0 di SnowLeopard. WTF dengan versi yang ditambahkan? Berarti pernyataan kasus sederhana tidak akan berfungsi.
mxcl
16
Ini bukan masalah besar untuk menghapusnya:os=${OSTYPE//[0-9.]/}
Abach
86
case $OSTYPE in darwin*) echo I am a Mac ;; esac
tripleee
36
@ tripleee atau untuk orang yang lebih nyaman dengan sintaks "jika":if [[ $OSTYPE == darwin* ]]; then echo I am a Mac;fi
Rican7
159

$OSTYPE

Anda cukup menggunakan $OSTYPEvariabel yang sudah ditentukan, misalnya:

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

Namun itu tidak dikenali oleh cangkang yang lebih lama (seperti cangkang Bourne ).


uname

Metode lain adalah mendeteksi platform berdasarkan unameperintah.

Lihat skrip berikut (siap untuk disertakan dalam .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

Anda dapat menemukan beberapa contoh praktis di blog saya.bashrc .


Ini adalah versi yang mirip dengan yang digunakan pada 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
kenorb
sumber
1
Cek $ OSTYPE tidak memiliki cabang untuk cygwin, yang mengindikasikan mesin windows. Pemeriksaan uname tidak akan berfungsi dengan baik, pada cygwin pengembalian uname "CYGWIN_NT-10.0" dan pada MinGW pengembalian uname "MINGW64_NT-10.0".
Matt Pennington
1
alias ls = '/ bin / ls -G' sebenarnya adalah opsi yang aman, dalam konteks rokok berbasis OS lihat superuser.com/a/1299969/84662
Andrei Neculau
Saya sarankan menggunakan uname, Oracle telah mengkilap konvensi dan meletakkan string versi gratis dengan mereka OSTYPE ==> solaris2.11. unamesedikit lebih bersih dan lebih sedikit pekerjaan yang harus dilakukan.
Akan
37

Mendeteksi sistem operasi dan jenis CPU tidak begitu mudah dilakukan portable . Saya memiliki shskrip sekitar 100 baris yang bekerja di beragam platform Unix yang sangat luas: sistem apa pun yang telah saya gunakan sejak 1988.

Elemen kuncinya adalah

  • uname -padalah jenis prosesor tetapi biasanya unknownpada platform Unix modern.

  • uname -m akan memberikan "nama perangkat keras mesin" pada beberapa sistem Unix.

  • /bin/arch, jika ada, biasanya akan memberikan jenis prosesor.

  • uname tanpa argumen akan memberi nama sistem operasi.

Akhirnya Anda harus memikirkan perbedaan antara platform dan seberapa baik Anda ingin membuatnya. Misalnya, hanya untuk menjaga hal-hal sederhana, saya memperlakukan i386melalui i686, setiap " Pentium*" dan setiap " AMD*Athlon*" semua sebagai x86.

Saya ~/.profilemenjalankan skrip saat startup yang menetapkan satu variabel ke string yang menunjukkan kombinasi CPU dan sistem operasi. Saya memiliki platform-spesifik bin, man, lib, dan includedirektori yang mendapatkan dibentuk berdasarkan itu. Kemudian saya menetapkan variabel lingkungan boatload. Jadi misalnya, skrip shell untuk memformat ulang surat dapat memanggil, misalnya, $LIB/mailfmtyang merupakan biner yang dapat dieksekusi platform-spesifik.

Jika Anda ingin mengambil jalan pintas , uname -mdan polos unameakan memberi tahu Anda apa yang ingin Anda ketahui di banyak platform. Tambahkan hal-hal lain saat Anda membutuhkannya. (Dan gunakan case, tidak bersarang if!)

Norman Ramsey
sumber
2
Menurut Perintah uname , uname tanpa parameter sama dengan menggunakan parameter "-s": "-s Menampilkan nama sistem. Bendera ini diaktifkan secara default.". Untuk menjadi eksplisit seseorang dapat menggunakan "uname -s" bukannya "uname". (Diuraikan agak dalam jawaban untuk 'bantuan keluaran Shell' )
Peter Mortensen
Apakah Anda memiliki tautan ke github git atau pastebin dengan skrip 100 ini untuk mendeteksi OS dan arsitektur prosesor dengan andal?
Andrew De Andrade
4
@AndrewDeAndrade Saya malu mengekspos kode ini kepada publik. pastebin.com/J66Lj6wf
Norman Ramsey
jadi bagaimana dengan uname -s?
Alexander Mills
35

Saya merekomendasikan untuk menggunakan kode bash lengkap ini

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

lebih banyak contoh contoh di sini: https://github.com/coto/server-easy-install/blob/master/lib/core.sh

coto
sumber
1
Anda meninggalkan fungsi huruf kecil, saya memperbarui jawaban Anda untuk Anda.
Robin Clowers
1
Setelah Anda tahu itu Linux, jika Anda hanya mencari-cari (tidak mencoba mengotomatisasi mencari tahu), sepertinya langkah termudah adalah dengan hanya ls /etcdan mencari "blah-release" - apa pun bla itu, itulah OS Linux - CentOS, Ubuntu , dll
Chris Moschini
1
Saya mengedit karena beberapa referensi ke variabel OS ditulis sebagai "{$ OS}" Saya mengubahnya menjadi "$ {OS}" itu cara yang benar, saya mengujinya
bazz
apakah Anda ingin menambahkan "echo $ {OS}" di bagian paling akhir skrip?
Oleg Kokorin
10

Dalam bash, gunakan $OSTYPEdan $HOSTTYPE, seperti yang didokumentasikan; Inilah yang saya lakukan. Jika itu tidak cukup, dan jika bahkan unameatau uname -a(atau opsi lain yang sesuai) tidak memberikan informasi yang cukup, selalu ada skrip config.guess dari proyek GNU, dibuat persis untuk tujuan ini.

Teddy
sumber
10

Saya sarankan menghindari beberapa jawaban ini. Jangan lupa bahwa Anda dapat memilih bentuk perbandingan string lain, yang akan menghapus sebagian besar variasi, atau kode jelek yang ditawarkan.

Salah satu solusi tersebut adalah pemeriksaan sederhana, seperti:

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

Yang memiliki manfaat tambahan untuk mencocokkan versi Darwin apa pun, meskipun sufiks versi itu. Ini juga berfungsi untuk variasi yang Linuxdiharapkan.

Anda dapat melihat beberapa contoh tambahan dalam dotfile saya di sini

Akiva
sumber
9

Coba gunakan "uname". Misalnya, di Linux: "uname -a".

Menurut halaman buku panduan, uname sesuai dengan SVr4 dan POSIX, jadi itu harus tersedia di Mac OS X dan Cygwin juga, tapi saya tidak bisa memastikannya.

BTW: $ OSTYPE juga disetel ke linux-gnusini :)

Joao da Silva
sumber
Tanpa parameter, uname mencetak 'Darwin' di Mac OS X (leopard). Dengan -a ia mencetak banyak informasi tambahan (versi kernel, arsitektur, dan hal lain yang tidak dapat saya pecahkan). Saya tidak dapat menguji pada cygwin
David Rodríguez - dribeas
8

Saya menulis gula ini di .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" ]];
}

Jadi saya bisa melakukan hal-hal seperti:

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"
perbaikan
sumber
BTW, 9 baris ini bekerja pada Bash apa saja yang berjalan di hampir semua hal. Tidak ada shellout dan berfungsi dengan hampir semua gaya .bashrc pribadi (pohon if / case bersarang besar atau banyak alias acak). IMO, hentakkan celananya dari setiap jawaban di atasnya.
kfix
Sejauh ini, terdekat untuk diselesaikan termasuk Cygwin dan BSD lainnya (pada dasarnya kompilasi dari * NIX populer)
HidekiAI
Lengkap untuk lahan pengguna yang relevan hari ini dan jalankan Bash. Pengguna AIX / HP-UX / IRIX / OpenVMS dapat berpadu. Subsistem Windows untuk Linux yang baru menjalankan stock amd64 yang diinstal oleh Ubuntu sehingga harus benar untuk keduanya if_nix gnu& if_os linux.
kfix
1
@ memperbaiki ya itu benar, win 10 subsistem keluaran bash "linux-gnu" untuk echo $OSTYPE. Untuk mendeteksi win 10 subsistem bash secara khusus, satu-satunya solusi yang saya temukan adalah memeriksa "Microsoft" di/proc/sys/kernel/osrelease
Jpnh
7
uname

atau

uname -a

jika Anda menginginkan informasi lebih lanjut

Federico A. Ramponi
sumber
7

Saya menulis perpustakaan Bash pribadi dan kerangka kerja skrip yang menggunakan GNU shtool untuk melakukan deteksi platform yang agak akurat.

GNU shtool adalah sekumpulan skrip yang sangat portabel yang berisi, di antara hal-hal lain yang bermanfaat, perintah 'platform shtool'. Ini adalah output dari:

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

pada beberapa mesin yang berbeda:

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)

Ini menghasilkan hasil yang cukup memuaskan, seperti yang Anda lihat. GNU shtool agak lambat, jadi saya benar-benar menyimpan dan memperbarui identifikasi platform dalam file di sistem yang dipanggil oleh skrip saya. Ini kerangka saya, jadi itu berfungsi untuk saya, tetapi jarak tempuh Anda mungkin berbeda.

Sekarang, Anda harus menemukan cara untuk mengemas shtool dengan skrip Anda, tetapi ini bukan latihan yang sulit. Anda selalu dapat kembali menggunakan output yang tidak sama.

EDIT:

Saya melewatkan posting oleh Teddy tentang config.guess(entah bagaimana). Ini adalah skrip yang sangat mirip, tetapi tidak sama. Saya pribadi menggunakan shtool untuk kegunaan lain juga, dan itu sudah bekerja dengan baik untuk saya.

senjata
sumber
7

Anda dapat menggunakan yang berikut ini:

OS=$(uname -s)

maka Anda dapat menggunakan variabel OS dalam skrip Anda.

Chetan kapoor
sumber
dapatkah Anda menjelaskan uname -sperbedaannya uname?
Alexander Mills
@AlexanderMills -s, --kernel-name cetak nama kernel
Chetan kapoor
6

Di bawah ini adalah pendekatan untuk mendeteksi OS Linux berbasis Debian dan RedHat dengan menggunakan / etc / lsb-release dan / etc / os-release (tergantung pada rasa Linux yang Anda gunakan) dan lakukan tindakan sederhana berdasarkan itu.

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

Contoh keluaran untuk 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] 
...            
Exequiel Barrirero
sumber
5

Ini harus aman digunakan di semua distro.

$ cat /etc/*release

Ini menghasilkan sesuatu seperti ini.

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

Ekstrak / tetapkan ke variabel sesuai keinginan

Catatan: Pada beberapa pengaturan. Ini juga dapat memberi Anda beberapa kesalahan yang dapat Anda abaikan.

     cat: /etc/upstream-release: Is a directory
RJ
sumber
Catatan: pada CentOS, ini memberikan[user@host ~]$ cat /etc/*release CentOS release 6.4 (Final) CentOS release 6.4 (Final) CentOS release 6.4 (Final)
cfstras
Ya, output yang saya posting adalah contoh, dari salah satu laptop saya, bukan konten statis yang Anda lihat di mana-mana.
RJ
Baru saja menambahkan bahwa tidak ada yang akan berpikir hasilnya selalu dalam bentuk yang sama :)
cfstras
1
+1 Saya menggunakan set -e pada awal skrip (Dengan demikian solusi ini tidak berfungsi doxer.org/linux-shell-centos-debian-ostype ). Dan solusi lain tidak secara khusus CentOS. Tetapi saya menemukan referensi ini yang membuktikan jawaban ini unix.stackexchange.com/a/92212
gihanchanuka
4
tidak berfungsi untuk Mac:cat: /etc/*release: No such file or directory
eridal
3

coba ini:

DISTRO=$(cat /etc/*-release | grep -w NAME | cut -d= -f2 | tr -d '"')
echo "Determined platform: $DISTRO"
Alexander Nekrasov
sumber
Di macOS saya dapatkancat: /etc/*-release: No such file or directory
csexton
@csexton sungguh, saya mendapatkan hal yang sama: zsh: no matches found: /etc/*release- ini hanya akan bekerja untuk sistem linux, saya kira ...
Alexander Nekrasov
Jawaban ini hanya berfungsi untuk Linux, pasti. Tetapi jawaban lain hanya mampu mendeteksi Linux yang bertentangan dengan sistem lain saja. Penemuan dasar ini sama sekali tidak membantu untuk menemukan distribusi Linux tertentu sama pentingnya dengan membedakan antara FreeBSD dan Darwin.
Thomas Urban
3

Anda dapat menggunakan berikut ini jika klausa dan perluas sesuai kebutuhan:

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

Saya mencoba pesan-pesan di atas di beberapa distro Linux dan menemukan yang berikut ini berfungsi paling baik untuk saya. Ini adalah jawaban kata singkat dan ringkas yang bekerja untuk Bash di Windows juga.

OS=$(cat /etc/*release | grep ^NAME | tr -d 'NAME="') #$ echo $OS # Ubuntu
intellilogic
sumber
2
Sementara cuplikan kode ini diterima, dan dapat memberikan bantuan, akan sangat ditingkatkan jika menyertakan penjelasan tentang bagaimana dan mengapa ini menyelesaikan masalah. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang! Harap edit jawaban Anda untuk menambahkan penjelasan, dan berikan indikasi batasan dan asumsi apa yang berlaku.
Toby Speight
1
Tampaknya bagus dan singkat untuk sebagian besar sistem linux, tapi sayangnya ini akan menghasilkan kesalahan pada macOS. Mungkin ini lebih "mendeteksi rasa distribusi linux dari Bash
csexton
1
@csexton OS=$( ([[ -f /etc/*release ]] && cat /etc/*release | grep ^NAME | tr -d 'NAME="') || echo "Unknown" )ini akan berfungsi tanpa membuang kesalahan.
Kuzeko
Sebenarnya, ini cara yang benarOS=$( $(compgen -G "/etc/*release" > /dev/null) && cat /etc/*release | grep ^NAME | tr -d 'NAME="') || $( echo "${OSTYPE//[0-9.]/}")
Kuzeko
@ Kuzeko Sayangnya saya masih mendapatkan kesalahan menjalankan ini di macOS.
csexton
1

Saya cenderung menyimpan .bashrc dan .bash_alias pada file yang dapat diakses semua platform. Inilah cara saya mengatasi masalah di .bash_alias saya:

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

Dan saya punya contoh .bash_alias_Linux dengan:

alias ls='ls --color=auto'

Dengan cara ini saya menjaga platform khusus dan kode portabel terpisah, Anda dapat melakukan hal yang sama untuk .bashrc

ericcurtin
sumber
1

Ini memeriksa banyak knownfile yang akan dikenali jika distro linux adalah Debian atau Ubunu, maka distro default ke $OSTYPEvariabel.

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"
Kuzeko
sumber
-1

Melakukan hal berikut membantu melakukan pemeriksaan dengan benar untuk ubuntu:

if [[ "$OSTYPE" =~ ^linux ]]; then
    sudo apt-get install <some-package>
fi
sandman
sumber
4
Bagaimana dengan sistem Linux lain yang tidak menggunakan apt-get?
Wilf
ubuntu adalah distribusi, bukan kelas sistem operasi.
Jitter