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 ?


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

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.


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.


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

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!)


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


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.


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


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 :)


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"

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

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.


7

Anda dapat menggunakan yang berikut ini:

OS=$(uname -s)

maka Anda dapat menggunakan variabel OS dalam skrip Anda.


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] 
...            

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

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"

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

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

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


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"

-1

Melakukan hal berikut membantu melakukan pemeriksaan dengan benar untuk ubuntu:

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

4
Bagaimana dengan sistem Linux lain yang tidak menggunakan apt-get?
Wilf

ubuntu adalah distribusi, bukan kelas sistem operasi.
Jitter
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.