Bagaimana saya bisa mendapatkan nama distribusi dan nomor versi dalam skrip shell sederhana?

191

Saya sedang mengerjakan skrip bash sederhana yang seharusnya dapat berjalan di distribusi Ubuntu dan CentOS (dukungan untuk Debian dan Fedora / RHEL akan menjadi nilai tambah) dan saya perlu tahu nama dan versi distribusi skrip yang sedang dijalankan ( untuk memicu tindakan tertentu, misalnya pembuatan repositori). Sejauh ini yang saya dapat adalah ini:

OS=$(awk '/DISTRIB_ID=/' /etc/*-release | sed 's/DISTRIB_ID=//' | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/')
VERSION=$(awk '/DISTRIB_RELEASE=/' /etc/*-release | sed 's/DISTRIB_RELEASE=//' | sed 's/[.]0/./')

if [ -z "$OS" ]; then
    OS=$(awk '{print $1}' /etc/*-release | tr '[:upper:]' '[:lower:]')
fi

if [ -z "$VERSION" ]; then
    VERSION=$(awk '{print $3}' /etc/*-release)
fi

echo $OS
echo $ARCH
echo $VERSION

Ini sepertinya berhasil, kembali ubuntuatau centos(saya belum mencoba yang lain) sebagai nama rilis. Namun, saya punya perasaan bahwa harus ada cara yang lebih mudah, lebih dapat diandalkan untuk menemukan ini - apakah itu benar?

Itu tidak bekerja untuk RedHat. / etc / redhat-release mengandung: Redhat Linux Entreprise release 5.5

Jadi, versi ini bukan kata ketiga, Anda sebaiknya menggunakan:

OS_MAJOR_VERSION=`sed -rn 's/.*([0-9])\.[0-9].*/\1/p' /etc/redhat-release`
OS_MINOR_VERSION=`sed -rn 's/.*[0-9].([0-9]).*/\1/p' /etc/redhat-release`
echo "RedHat/CentOS $OS_MAJOR_VERSION.$OS_MINOR_VERSION"
Alix Axel
sumber
Apakah Anda yakin +-releaseberhasil? Secara efektif Anda mencari dengan asumsi itu akan /etc/lsb-release, jadi mungkin sebut saja itu.
Mikel
@Mikel: Saya diganti *dengan +untuk menghindari pembentukan komentar, seharusnya etc/*-release, sepertinya berhasil.
Alix Axel
8
Jangan pernah memperkenalkan kesalahan sintaksis untuk mendapatkan pemformatan yang benar. Selain itu, formatnya salah hanya di pratinjau, tampilan akhir mengambil sintaks dari tag.
Gilles
Mengapa tidak ada yang menyebutkan fitur ini uname -rv | grep -i "name_of_distro"dan menggunakan kode keluar?
buron

Jawaban:

182

Untuk mendapatkan OSdan VER, tampaknya standar terbaru /etc/os-release. Sebelum itu, ada lsb_releasedan /etc/lsb-release. Sebelum itu, Anda harus mencari file yang berbeda untuk setiap distribusi.

Inilah yang saya sarankan

if [ -f /etc/os-release ]; then
    # freedesktop.org and systemd
    . /etc/os-release
    OS=$NAME
    VER=$VERSION_ID
elif type lsb_release >/dev/null 2>&1; then
    # linuxbase.org
    OS=$(lsb_release -si)
    VER=$(lsb_release -sr)
elif [ -f /etc/lsb-release ]; then
    # For some versions of Debian/Ubuntu without lsb_release command
    . /etc/lsb-release
    OS=$DISTRIB_ID
    VER=$DISTRIB_RELEASE
elif [ -f /etc/debian_version ]; then
    # Older Debian/Ubuntu/etc.
    OS=Debian
    VER=$(cat /etc/debian_version)
elif [ -f /etc/SuSe-release ]; then
    # Older SuSE/etc.
    ...
elif [ -f /etc/redhat-release ]; then
    # Older Red Hat, CentOS, etc.
    ...
else
    # Fall back to uname, e.g. "Linux <version>", also works for BSD, etc.
    OS=$(uname -s)
    VER=$(uname -r)
fi

Saya pikir unameuntuk mendapatkan ARCHmasih merupakan cara terbaik. Tetapi contoh yang Anda berikan jelas hanya menangani sistem Intel. Saya akan menyebutnya BITSseperti ini:

case $(uname -m) in
x86_64)
    BITS=64
    ;;
i*86)
    BITS=32
    ;;
*)
    BITS=?
    ;;
esac

Atau ubah ARCHmenjadi versi yang lebih umum, namun tidak ambigu: x86dan x64atau serupa:

case $(uname -m) in
x86_64)
    ARCH=x64  # or AMD64 or Intel64 or whatever
    ;;
i*86)
    ARCH=x86  # or IA32 or Intel32 or whatever
    ;;
*)
    # leave ARCH as-is
    ;;
esac

tapi tentu saja itu terserah kamu.

Mikel
sumber
2
Saya akan memeriksa lsb_release dan menggunakannya jika tersedia, tetapi tidak tersedia di mana-mana. Misalnya, itu tidak dalam instalasi default Fedora 14.
Steven D
Benarkah? Apakah Anda mencoba mengeja dengan -dan _? Mungkin di /lib/lsbatau di suatu tempat seperti itu. Apa yang rpm -qa "lsb*"dicetak?
Mikel
1
rpm -qa "lsb*tidak mencetak apa pun. Menurutnya yum provides */lsb_releaseterkandung dalam paket yang disebut redhat-lsb yang saya kira tidak diinstal secara default. Namun, saya bukan ahli Fedora, ini hanya hasil dari Fedora VM acak yang saya miliki dan bisa sangat salah.
Steven D
3
Baru saja menginstal Fedora 14 di VM, dan tidak ada lsb-release, seperti yang Anda katakan.
Mikel
5
Jangan gunakan $OS,, $VERSIONdll - dengan konvensi, kami menggunakan huruf besar untuk variabel lingkungan (PAGER, EDITOR, SHELL, ...) dan variabel shell internal (BASH_VERSION, RANDOM, ...). Semua nama variabel lainnya harus mengandung setidaknya satu huruf kecil. Konvensi ini menghindari variabel lingkungan dan internal yang secara tidak sengaja diabaikan.
Chris Down
58

Saya akan menggunakan ini sebagai langkah pertama:

ls /etc/*release

Gentoo, RedHat, Arch & SuSE memiliki file bernama eg /etc/gentoo-release. Tampaknya menjadi populer, periksa situs ini tentang rilis file .

Debian & Ubuntu harus memiliki /etc/lsb-releaseyang berisi info rilis juga, dan akan muncul dengan perintah sebelumnya.

Yang cepat lainnya adalah uname -rv. Jika kernel yang dipasang adalah kernel distro, biasanya Anda akan menemukan nama di sana.

Tikar
sumber
Di Debian, itu uname -a.
tshepang
2
tidak uname -rvmengandung info? uname -aakan mencetak hal-hal seperti jenis prosesor dan nama host yang tidak relevan di sini. (Tetapi kedua rilis kernel ( -r) dan versi ( -v) diperlukan, tidak semua distro melakukan hal yang sama di sana)
Mat
uname -r memberi 2.6.32-5-686-bigmemdan uname -v memberi #1 SMP Tue Mar 8 22:14:55 UTC 2011pada Debian 6. uname -a OTOH memberi Linux debian 2.6.32-5-686-bigmem #1 SMP Tue Mar 8 22:14:55 UTC 2011 i686 GNU/Linux.
tshepang
bagian kedua uname -aadalah -n, yaitu nodename == nama host. jadi saya katakan unametidak akan menarik pada Debian. Kalau dipikir-pikir, saya tidak yakin itu sangat berguna pada RedHat juga.
Mat
Oh oke. Jadi hanya karena keberuntungan saya menetapkan nama host saya sebagai default debian,.
tshepang
36

lsb_release -a. Bekerja pada Debian dan saya kira Ubuntu, tapi saya tidak yakin tentang sisanya. Biasanya itu harus ada di semua distribusi GNU / Linux karena terkait dengan LSB (Linux Standard Base).

sakisk
sumber
3
Ini tidak diinstal secara default di Gentoo. Itu bukan secara default pada Fedora baik di beberapa titik (mungkin sekarang meskipun)
Mat
2
Ini berhasil pada Debian squeeze, Fedora 14, dan OpenSUSE 11.3. Pada Debian dan SUSE paket yang berisi lsb_release adalah lsb-release, di Fedora itu redhat-lsb. Itu sudah diinstal pada Debian dan SUSE, tetapi tidak pada Fedora. Saya pikir ini adalah jawaban terbaik sejauh ini. +1.
Faheem Mitha
3
lsb_release bukan bagian dari instalasi minimal CentOS 6.
seorang pembuat kode
1
lsb_release -a mengembalikan "-bash: lsb_release: perintah tidak ditemukan" di Raspberry dengan Raspbian ( Debian 7.1 diturunkan).
Peter Mortensen
lsb_release -a bekerja pada Red Hat Enterprise Linux Server rilis 6.6 (Santiago)
jwilleke
21

Satu-liner, fallback, satu garis output, tidak ada kesalahan.

lsb_release -ds 2>/dev/null || cat /etc/*release 2>/dev/null | head -n1 || uname -om
Markus
sumber
Cantik terimakasih. Catatan ini masih tidak berfungsi di Mac OS X, tetapi berfungsi dengan baik di Ubuntu dan CentOS (yang merupakan tiga yang saya miliki).
Wildcard
2
Cemerlang! Mengapa jawaban yang begitu berani tidak ada di atas?
Neo
13
python -c "import platform;print(platform.platform())"

atau hanya

python -m platform
Ilya Kharlamov
sumber
9
  1. lsb- * tidak diinstal / tidak ada pada basis CentOS atau sistem Debian
  2. / proc / * tidak ada di OSX

Ambil kiat dari pengembang javascript. Jangan menguji versi, uji kemampuan. Itu tidak cantik, tetapi berhasil. Perluas sesuai kebutuhan.

function os_type
{
case `uname` in
  Linux )
     LINUX=1
     which yum && { echo centos; return; }
     which zypper && { echo opensuse; return; }
     which apt-get && { echo debian; return; }
     ;;
  Darwin )
     DARWIN=1
     ;;
  * )
     # Handle AmgiaOS, CPM, and modified cable modems here.
     ;;
esac
}  
Orwellophile
sumber
6
Yum bisa jadi Red Hat, Scientific Linux, atau Fedora. Ada perintah yang tepat untuk Fedora meniru Debian. Dan seterusnya. Hanya mengklasifikasikan apa saja dengan yum karena CentOS memberi Anda berbagai sistem yang didukung dari Red Hat 4 hingga Fedora 18, yaitu sekitar 8 tahun sejarah Linux di sana. Jika Anda perlu tahu apakah <foo> didukung, secara khusus periksa <foo> alih-alih menebak berdasarkan identifikasi distribusi (tidak dapat diandalkan)! Tentu, ini mengarah ke sesuatu yang mirip autotool, tapi itu tidak bisa membantu (cukup ucapkan terima kasih $ DEITY bahwa perang Unix telah berakhir).
vonbrand
@vonbrand memang, seperti yang Anda katakan. saya tidak mencoba untuk membedakan antara sub-rasa. dan urutan saya check-in (semoga) menghapus sebagian besar situasi rumit (RHEL dengan apt-install), meskipun saya tidak melakukan banyak penelitian. jika RHEL dapat diinstal secara tepat, dan pengguna Ubuntu memiliki yum ... yah, Anda hanya kurang beruntung.
Orwellophile
6

Agar sukses yang paling mungkin terjadi, ini:

cat /etc/*version
cat /proc/version #linprocfs/version for FreeBSD when "linux" enabled
cat /etc/*release
uname -rv

mencakup sebagian besar kasus (AFAIK): Debian, Ubuntu, Slackware, Suse, Redhat, Gentoo, * BSD dan mungkin yang lainnya.

Eelvex
sumber
cat /etc/*versiontidak berfungsi (tidak ada file seperti itu) di CentOS (setidaknya pada 6.4)
om-nom-nom
Jika Anda menjalankan perintah dalam sebuah wadah, / proc / version akan berisi versi distribusi HOST, dan bukan versi distribusi kontainer.
Dereckson
5

Untuk sebagian besar sistem OS Linux modern, file /etc/os-releaseini benar-benar menjadi standar dan dimasukkan dalam sebagian besar OS. Jadi di dalam skrip Bash Anda, Anda hanya bisa memasukkan file, dan Anda akan memiliki akses ke semua variabel yang dijelaskan di sini (misalnya: NAME, VERSION, ...)

Jadi saya hanya menggunakan ini dalam skrip Bash saya:

if [ -f /etc/os-release ]
then
        . /etc/os-release
else
        echo "ERROR: I need the file /etc/os-release to determine what my distribution is..."
        # If you want, you can include older or distribution specific files here...
        exit
fi
Chris Maes
sumber
3

Jika file /etc/debian_versionada, distribusinya adalah Debian, atau turunan Debian. File ini mungkin memiliki nomor rilis; pada mesin saya saat ini 6.0.1. Jika sedang diuji atau tidak stabil, itu mungkin mengatakan pengujian / tidak stabil, atau mungkin memiliki nomor rilis yang akan datang. Kesan saya adalah bahwa pada Ubuntu setidaknya, file ini selalu diuji / tidak stabil, dan bahwa mereka tidak memasukkan nomor rilis di dalamnya, tetapi seseorang dapat memperbaiki saya jika saya salah.

Fedora (setidaknya rilis terbaru), memiliki file serupa, yaitu /etc/fedora-release.

Faheem Mitha
sumber
Versi Debian yang lebih baru menggunakan / etc / os-release sebagai gantinya.
Dereckson
1
@ Dereckson saya memeriksa mesin wheezy saya, dan ia memiliki keduanya /etc/debian_versiondan /etc/os-release.
Faheem Mitha
Diuji dalam chroot Jessie yang dibuat dengan debootstrap. Namun memang, mesin lokal juga di bawah Jessie, kali ini diinstal dengan cara yang lebih konvensional, berisi /etc/debian_versionfile. Jadi cara kami mempersiapkan instalasi Debian dapat memengaruhi file rilis yang tersedia, itu menarik.
Dereckson
Debian os-releasetidak menyertakan nomor versi lengkap dari debian_version. Lihat unix.stackexchange.com/questions/382531 .
JdeBP
1

2 cara dari banyak:

1) gunakan

lsb_release -a

Saya mengujinya pada CentOS 5.5 dan Ubuntu 10.04

output untuk CentOS adalah:

LSB Version:    :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch 
Distributor ID: CentOS
Description:    CentOS release 5.5 (Final)
Release:        5.5
Codename:       Final

dan untuk Ubuntu adalah:

LSB Version:    :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: CentOS
Description:    CentOS release 5.5 (Final)
Release:        5.5
Codename:       Final

2) masukkan perintah berikut:

cat /etc/*-release

Saya mengujinya pada CentOS 5.5 dan Ubuntu 10.04, dan berfungsi dengan baik.

Sam
sumber
lsb_release tidak ada dalam CentOS 6 (min install fwiw)
a coder
lsb_release -a mengembalikan "-bash: lsb_release: perintah tidak ditemukan" di Raspberry dengan Raspbian ( Debian 7.1 diturunkan).
Peter Mortensen
0

Skrip ini berfungsi pada Debian, (mungkin perlu beberapa penyesuaian pada Ubuntu)

#!/usr/bin/env bash

echo "Finding Debian/ Ubuntu Codename..."

CODENAME=`cat /etc/*-release | grep "VERSION="`
CODENAME=${CODENAME##*\(}
CODENAME=${CODENAME%%\)*}

echo "$CODENAME"
# => saucy, precise, lucid, wheezy, squeeze
pengguna9869932
sumber
0

Ini adalah versi chech_distro sederhana saya. ^^;

#!/usr/bin/env bash
check_distro2(){
    if [[ -e /etc/redhat-release ]]
    then
      DISTRO=$(cat /etc/redhat-release)
    elif [[ -e /usr/bin/lsb_release ]]
    then
      DISTRO=$(lsb_release -d | awk -F ':' '{print $2}')
    elif [[ -e /etc/issue ]]
    then
      DISTRO=$(cat /etc/issue)
    else
      DISTRO=$(cat /proc/version)
    fi
    }

    check_distro2
    echo $DISTRO
niceguy oh
sumber
0

Tanpa versi, hanya dist:

cat /etc/issue | head -n +1 | awk '{print $1}'
coanor
sumber
Jawaban dari tahun sebelumnya oleh Yahya Yahyaoui mengatakan hal yang sama. Kedua jawaban ini sebenarnya ditujukan pada tahun 2011 dalam jawaban yang telah dihapus. Alasan mereka salah masih berlaku.
JdeBP
0

Ini diuji pada Ubuntu 14 dan CentOS 7

cat /etc/os-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g' | sed 's/["]//g' | awk '{print $1}'
BsdHelper
sumber
@don_crissti Bagaimana Anda melakukannya?
BsdHelper
sed -n -e '/PRETTY_NAME/ s/^.*=\|"\| .*//gp' /etc/os-release
cas
@ bisa sangat bagus! Menambahkan itu ke kotak alat saya. Terima kasih sudah berbagi.
BsdHelper
0

Saya menemukan skrip yang bagus dari sini yang berfungsi untuk sebagian besar distro linux yang umum:

#! /bin/bash
# return an awkable string consisting of
#    unix OS type, or
#    Linux dist, or
#    a long guess (based on /proc), or
#    no clue

giveUp () {
   echo "Unknown"
   exit 0
}

# keep this easily awkable, prepending an initial clue
versionGuess () {
   if [ -e /proc/version ]; then
      echo -n "Unsure "
      cat /proc/version
      exit 0
   fi
   return 1
}

# if we have ignition, print and exit
gotDist () {
   [ -n "$1" ] && echo "$1" && exit 0
}

# we are only interested in a single word "dist" here
# various malformations can occur; admin will have to code appropately based on output
linuxRelease () {
   if [ -r /etc/lsb-release ]; then
      dist=$(grep 'DISTRIB_ID' /etc/lsb-release | sed 's/DISTRIB_ID=//' | head -1)
      gotDist "$dist"
   fi

   dist=$(find /etc/ -maxdepth 1 -name '*release' 2> /dev/null | sed 's/\/etc\///' | sed 's/-release//' | head -1)
   gotDist "$dist"

   dist=$(find /etc/ -maxdepth 1 -name '*version' 2> /dev/null | sed 's/\/etc\///' | sed 's/-version//' | head -1)
   gotDist "$dist"

   return 1
}

# start with uname and branch the decision from there
dist=$(uname -s 2> /dev/null)
if [ "$dist" = "Linux" ]; then
   linuxRelease
   versionGuess
   giveUp
elif [ -n "$dist" ]; then
   echo "$dist"
   exit 0
else
   versionGuess
   giveUp
fi

# we shouldn't get here
giveUp
# done
Mithril
sumber
0

Ada permata ruby facter , yang memberi Anda beberapa fakta tentang OS os, itu menganalisis file rilis OS, data lain dan cetakan ke layar terminal. Anda dapat mencoba sebagai berikut, dimulai dengan instalasi rubygems:

# apt-get install rubygems

Silakan gunakan case di atas yang memenuhi syarat untuk OS Anda. Kemudian instal permata itu sendiri.

# gem install facter

Kemudian gunakan:

$ facter

CATATAN: Lihat sumber permata facter untuk mendapatkan info lebih lanjut dalam pemasangan.

Малъ Скрылевъ
sumber
0

Jika seseorang membutuhkan distro juga:

#!/usr/bin/env bash

LINUX_VERSION_NAME=`lsb_release -sr`


# Distribution specific installation
if [[ ${LINUX_VERSION_NAME} == "18.04" ]]
then
    echo "It is: ${LINUX_VERSION_NAME}"

else
    echo "It is not ${LINUX_VERSION_NAME}"
fi

Keluaran:

It is: 18.04

Ubah ke: lsb_release -sc untuk mendapatkan distro:

LINUX_VERSION_NAME=`lsb_release -sc`


# Distribution specific installation
if [[ ${LINUX_VERSION_NAME} == "bionic" ]]
then
    echo "It is: ${LINUX_VERSION_NAME}"

else
    echo "It is not ${LINUX_VERSION_NAME}"
fi

Keluaran:

It is: bionic
jturi
sumber
-3

Perintah ini berfungsi untuk distribusi berbasis Debian dan Redhat: Menggunakan trfilter, Anda mengonversi dokumen ke format satu kata per baris dan kemudian menghitung baris pertama yang berisi nama distribusi.

tr -s ' \011' '\012' < /etc/issue | head -n 1
Yahya Yahyaoui
sumber
Komentar pada jawaban yang sekarang dihapus dari 2011 yang mengatakan hal yang sama, masih berlaku. Seperti halnya jawaban yang salah tempat, sekali lagi sekarang dihapus, yang mengatakan bahwa /etc/issuetidak mengandung versi atau nama di zenwalk. Ini adalah file yang dapat dimodifikasi administrator yang berisi pesan yang disajikan kepada manusia yang tidak memiliki jaminan mengandung apa pun yang dapat ditarik secara programatik.
JdeBP