Як я можу отримати ім'я розповсюдження та номер версії у простому скрипті оболонки?


191

Я працюю над простим сценарієм bash, який повинен мати можливість працювати на дистрибутивах Ubuntu та CentOS (підтримка Debian і Fedora / RHEL була б плюсом), і мені потрібно знати ім'я та версію дистрибутива, за допомогою якого працює сценарій ( щоб викликати конкретні дії, наприклад, створення сховищ). Поки що у мене це:

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

Це , здається , працювати, повертаючись ubuntuабо centos(я не пробував інші) в якості імені випуску. Однак у мене є відчуття, що повинен бути простіший, надійніший спосіб знайти це - це правда?

Це не працює для RedHat. / etc / redhat-release містить: Redhat Linux Entreprise 5.5

Отже, версія не є третім словом, вам краще скористатися:

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"

Ви впевнені, що +-releaseпрацює? Ви ефективно шукаєте, припускаючи, що так буде /etc/lsb-release, тому, можливо, просто так називайте.
Мікель

@Mikel: Я замінив *на те, +щоб уникнути форматування коментарів, це etc/*-release, мабуть, працює.
Алікс Аксель

8
Ніколи не вводьте синтаксичну помилку, щоб отримати правильне форматування. Крім того, форматування помилкове лише в попередньому перегляді, остаточний вигляд підбирає синтаксис з тегів.
Жиль

Чому ніхто не згадує про цей fe uname -rv | grep -i "name_of_distro"і не використовує код виходу?
втікач

Відповіді:


182

Щоб отримати OSі VER, здається, останній стандарт /etc/os-release. До цього було lsb_releaseі /etc/lsb-release. Перед цим вам довелося шукати різні файли для кожного розподілу.

Ось що я б запропонував

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

Я думаю, unameщо ARCHце все-таки найкращий спосіб. Але приклад, який ви навели, очевидно, лише обробляє системи Intel. Я б це назвав BITSтак:

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

Або змінити ARCHна більш поширені, але однозначні версії: x86і x64або подібні:

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

але звичайно це залежить від вас.


2
Я би перевірив наявність lsb_release і використовував би його, якщо він є, але він доступний не скрізь. Наприклад, це не в стандартній установці Fedora 14.
Стівен Д,

Дійсно? Чи пробували ви написання його -і _? Можливо, це все-таки /lib/lsbчи десь так. Що означає rpm -qa "lsb*"друк?
Мікель

1
rpm -qa "lsb*нічого не друкує. Згідно з yum provides */lsb_releaseцим він міститься в пакеті з назвою redhat-lsb, який, напевно, не встановлений за замовчуванням. Однак я не є експертом Fedora, це лише результати випадкового VM Fedora, який я маю, і міг бути дуже помилковим.
Стівен Д

3
Щойно встановили Fedora 14 у віртуальний комп'ютер, і немає lsb-release, як ви сказали.
Мікель

5
Не використовуйте $OS, $VERSIONтощо - за домовленістю, ми використовуємо великі розміри змінних середовища (PAGER, EDITOR, SHELL, ...) та внутрішніх змінних оболонок (BASH_VERSION, RANDOM, ...). Усі інші назви змінних повинні містити принаймні одну малу літеру. Ця конвенція дозволяє уникнути випадкових переваг екологічних та внутрішніх змінних.
Кріс Даун

58

Я б пішов із цим як перший крок:

ls /etc/*release

Gentoo, RedHat, Arch & SuSE є файл з ім'ям , наприклад /etc/gentoo-release. Здається, що це популярно, перегляньте цей сайт щодо файлів релізів .

У Debian & Ubuntu також має бути інформація про /etc/lsb-releaseвипуск, яка відображатиметься з попередньою командою.

Ще один швидкий uname -rv. Якщо встановлене ядро ​​- це ядро ​​дистрибутива акцій, зазвичай іноді знайдете його ім'я.


У Debian це uname -a.
thepang

2
не uname -rvмістить інформацію, хоча? uname -aбуде надрукувати такі речі, як тип процесора та ім'я хоста, які тут не мають значення. (Але випуск ядра ( -r) і версія ( -v) необхідні, не всі дистрибутиви роблять це те саме)
Мат,

uname -r дає 2.6.32-5-686-bigmemі uname -v дає #1 SMP Tue Mar 8 22:14:55 UTC 2011на Debian 6. uname -a OTOH дає Linux debian 2.6.32-5-686-bigmem #1 SMP Tue Mar 8 22:14:55 UTC 2011 i686 GNU/Linux.
thepang

друга частина uname -aє -n, тобто nodename == ім'я хоста. тому я б сказав uname, що на Debian не буде цікаво. Подумайте про це, я не впевнений, що це так корисно і на RedHat.
Мат

О, добре. Так що це просто удача , що я встановив мій ім'я хоста за замовчуванням, debian.
thepang

36

lsb_release -a. Працює над Debian, і я думаю, що Ubuntu, але в іншому я не впевнений. Зазвичай він повинен існувати у всіх дистрибутивах GNU / Linux, оскільки це пов'язано з LSB (Linux Standard Base).


3
Він не встановлений за замовчуванням у Gentoo. Це не було за замовчуванням у Fedora або в якийсь момент (мабуть, зараз це є)
Мат

2
Це працювало на Debian скресл, Fedora 14 та OpenSUSE 11.3. У Debian і SUSE пакет, що містить lsb_release, був lsb-release, на Fedora - redhat-lsb. Він уже був встановлений на Debian і SUSE, але не на Fedora. Я думаю, що це найкраща відповідь поки що. +1.
Faheem Mitha

3
lsb_release не є частиною мінімальної установки CentOS 6.
кодер

1
lsb_release -a повертає "-bash: lsb_release: команда не знайдена" на Raspberry with Raspbian ( похідне Debian 7.1).
Пітер Мортенсен

lsb_release-працює над випуском сервера Red Hat Enterprise Linux 6.6 (Сантьяго)
jwilleke

21

Однолінійний, резервний запас, один рядок виводу, помилок немає.

lsb_release -ds 2>/dev/null || cat /etc/*release 2>/dev/null | head -n1 || uname -om

Красиво, дякую. Зауважте, це все ще не працює на Mac OS X, але він відмінно працює на Ubuntu та CentOS (які є трьома, які мені зручні).
Wildcard

2
Блискуче! Чому така надійна відповідь не вгорі?
Нео


9
  1. lsb- * не встановлено / не існує в базових системах CentOS або Debian
  2. / proc / * не існує на OSX

Підкажіть розробники javascript. Не тестуйте на версію, не перевіряйте працездатність. Це не дуже, але це працює. Розгорніть по мірі необхідності.

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
}  

6
Yum цілком може бути Red Hat, Scientific Linux або Fedora. Існувала влучна команда для Fedora, що наслідує Debian. І так далі. Просто класифікуючи що-небудь з yum, як CentOS дає вам ряд підтримуваних систем від Red Hat 4 до Fedora 18, тобто приблизно 8 років історії Linux саме там. Якщо вам потрібно знати, чи підтримується <foo>, спеціально перевірте наявність <foo> замість того, щоб здогадуватися на основі (ненадійної) ідентифікації розповсюдження! Звичайно, це призводить до чимось хибним автоінструментів, але це не може допомогти (просто дякую $ DEITY, що війни Unix закінчилися).
фонбранд

@vonbrand дійсно, це, як ви кажете. я не намагаюся розмежовувати між субмаринами. і замовлення, на яке я заїжджаю (сподіваюсь), усуває більшість складних ситуацій (RHEL з apt-get install), хоча я не робила багато досліджень. якщо RHEL може бути встановлений apt-get, а користувачі Ubuntu мають yum ... ну, ви просто від удачі.
Орвелофіл

6

Для найімовірнішого успіху такі:

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

охоплює більшість випадків (AFAIK): Debian, Ubuntu, Slackware, Suse, Redhat, Gentoo, * BSD та, можливо, інші.


cat /etc/*versionне працює (немає такого файлу) на CentOS (принаймні, на 6.4)
om-nom-nom

Якщо ви запускаєте команду в контейнері, / proc / версія буде містити версію дистрибутива HOST, а не розсилку контейнера.
Дерексон

5

У більшості сучасних систем ОС Linux файл /etc/os-releaseдійсно стає стандартним і входить до більшості ОС. Отже, всередині вашого сценарію Bash ви можете просто включити файл, і ви отримаєте доступ до всіх описаних тут змінних (наприклад: NAME, VERSION, ...)

Тому я просто використовую це у своєму сценарії Bash:

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

3

Якщо файл /etc/debian_versionіснує, дистрибутив є Debian або похідним Debian. Цей файл може мати номер випуску; на моїй машині це зараз 6.0.1. Якщо він тестується або нестабільний, він може сказати тестування / нестабільний, або він може мати номер майбутнього випуску. Моє враження, що принаймні в Ubuntu цей файл завжди тестується / нестабільний, і вони не ставлять у ньому номер випуску, але хтось може мене виправити, якщо я помиляюся.

Fedora (принаймні останні випуски) мають подібний файл, а саме /etc/fedora-release.


Новіші версії Debian замість цього використовують / etc / os-release.
Дерексон

1
@Dereckson Я перевірив свою хрипку машину, і вона має і те, /etc/debian_versionі /etc/os-release.
Faheem Mitha

Випробуваний на Chroot Jessie, створений за допомогою debootstrap. Але дійсно, місцева машина також під Джессі, цього разу встановлена ​​більш звичайним способом, містить /etc/debian_versionфайл. Тож те, як ми готуємо установку Debian, може вплинути на доступні файли випуску, це цікаво.
Дерексон

Debian's os-releaseне включає повний номер версії від debian_version. Дивіться unix.stackexchange.com/questions/382531 .
JdeBP

2

Якщо ви не можете або не хочете використовувати файл випуску LSB (через залежності, який приносить пакет), ви можете шукати файли випуску, що стосуються конкретного дистрибутива. Bcfg2 має зонд для дистрибутива, який ви можете використовувати: http://trac.mcs.anl.gov/projects/bcfg2/browser/doc/server/plugins/probes/group.txt


1

2 способи з багатьох:

1) використання

lsb_release -a

Я тестував його на CentOS 5.5 та Ubuntu 10.04

вихід для CentOS:

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

а для Ubuntu є:

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) введіть таку команду:

cat /etc/*-release

Я тестував його на CentOS 5.5 і Ubuntu 10.04, і він працює чудово.


lsb_release не в CentOS 6 (хв. встановити fwiw)
кодер

lsb_release -a повертає "-bash: lsb_release: команда не знайдена" на Raspberry with Raspbian ( похідне Debian 7.1).
Пітер Мортенсен

0

Цей скрипт працює на Debian (може знадобитися певна настройка на 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

0

Ось моя проста версія chech_distro. ^^;

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

0

Без версії, тільки тільки dist:

cat /etc/issue | head -n +1 | awk '{print $1}'

Відповідь Яхя Яхяуї на рік раніше сказала те саме. Обидві ці відповіді були фактично розглянуті у 2011 році у відповідях, які з тих пір були видалені. Причини того, що вони помиляються, все ще діють.
JdeBP

0

Це було протестовано на Ubuntu 14 та CentOS 7

cat /etc/os-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g' | sed 's/["]//g' | awk '{print $1}'

@don_crissti Як би ти це зробив?
BsdHelper

sed -n -e '/PRETTY_NAME/ s/^.*=\|"\| .*//gp' /etc/os-release
cas

@cas Дуже приємно! Додаю це до моєї панелі інструментів. Дякую, що поділився.
BsdHelper

0

Я вважаю , хороший сценарій звідси , який працює для більшості поширеного dists Linux:

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


0

Існує найважливіший коштовний камінь з рубіном, який дає вам деякі факти про OS OS, він аналізує файли випуску ОС, інші дані та друкує на екран терміналу. Можна спробувати наступне, починаючи з установки рубігем:

# apt-get install rubygems

Будь ласка, використовуйте випадок вище, який відповідає вашій ОС. Потім встановіть самоцвіт.

# gem install facter

Потім використовуйте:

$ facter

ПРИМІТКА. Щоб отримати докладнішу інформацію про встановлення, перегляньте джерела дорогоцінних каменів.


0

Якщо комусь також потрібен дистрибутив:

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

Вихід:

It is: 18.04

Змініть на: lsb_release -sc, щоб отримати дистрибутив:

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

Вихід:

It is: bionic

-3

Ця команда працює для дистрибутивів на основі Debian і Redhat: Використовуючи trфільтр, ви перетворюєте документ у формат одного слова на рядок, а потім підраховуєте перший рядок, який містить ім'я розповсюдження.

tr -s ' \011' '\012' < /etc/issue | head -n 1

Коментарі до видаленої відповіді від 2011 року, яка сказала те саме, все ще застосовуються. Як і неправильно розміщена відповідь, знову видалена, що сказала, що /etc/issueне містить версії та імені на zenwalk. Це файл, який може змінюватися адміністратором, що містить повідомлення, представлене людям, яке не має гарантій, що містить щось, що можна витягнути програмно.
JdeBP
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.