Як дізнатися, яка версія Linux працює?


29

Іноді ваші сценарії повинні поводитися по-різному в різних Linux. Як я можу визначити, на якій версії Linux працює сценарій?


1
Під версією ви маєте на увазі версію ядра? Який розподіл? Версія distro?
Кріс Upchurch

2
Я впевнений, що jldugger хоче з'ясувати, в якій родині дистрибутива працює система. Версія ядра навряд чи вплине на скрипт, якщо це не залежить від деяких / sys або / proc матеріалів - і навіть тоді, як правило, простіше вважати на основі розподілу, ніж на ядрі.
Міхай Лімбашан

Відповіді:


27

Не намагайтеся робити припущення, засновані на дистрофії щодо того, що ви можете, а що не можете робити, тому що в цьому криється безумство (див. Також "Виявлення агента користувача"). Натомість виявіть, чи підтримується те, що ви хочете зробити, і як це робиться за допомогою будь-якої команди чи файлу, яке ви хочете використовувати.

Наприклад, якщо ви хотіли встановити пакет, ви можете виявити, чи є у вас система Debian або схожа на RedHat, перевіривши наявність dpkg або rpm (спочатку перевірте наявність dpkg, оскільки машини Debian можуть мати команда rpm на них ...). Приймайте рішення щодо того, що робити, виходячи з цього, а не лише на те, чи це система Debian чи RedHat. Таким чином, ви автоматично підтримуватимете будь-які похідні дистрибутиви, на які ви явно не запрограмували. О, і якщо ваш пакет вимагає конкретних залежностей, то протестуйте їх також і повідомте користувачеві про те, чого вони відсутні.

Інший приклад - це спіткання з мережевими інтерфейсами. Розробіть, що робити, виходячи з того, чи є файл / etc / network / interfaces або каталог / etc / sysconfig / network-script, і перейдіть звідти.

Так, це більше роботи, але якщо ви не хочете переробити всі помилки, допущені веб-розробниками за останнє десятиліття або більше, ви зробите це розумним шляхом з самого початку.


1
(Розгортається на цю відповідь) В деяких ситуаціях виявлення особливостей бажано, але переконайтеся, що ви ніколи не намагаєтеся вгадати розподіл за виявленими вами функціями! Не перечитуйте відповідь і не з’ясуйте, чи є платформа RedHat на основі того, які файли в / і т.д. Якщо вам дійсно потрібна назва розповсюдження, перевірте lsb_release (або / etc / redhat-release тощо).
Ніколас Вілсон

36

Не існує способу перехресного розподілу. Однак:

  • Redhat та друзі: перевірити /etc/redhat-release, перевірити вміст
  • Debian: перевірка /etc/debian_version, перевірка вмісту
  • Мандріва та друзі: перевірити /etc/version, перевірити вміст
  • Slackware: перевірити /etc/slackware-version, перевірити вміст

Взагалі кажучи, перевірити наявність /etc/*-releaseта /etc/*-version.


Редагувати: Знайдений старий (1+ років) скрипт моїх, що лежав навколо, що я, мабуть, обмотався разом (у ньому є вражаючий журнал CVS, що повертається 6 років.) Він більше не може працювати належним чином, як є, і я можу Не завадить знайти встановлені дистрибутиви для перевірки, але це повинно дати вам хорошу вихідну точку. Він чудово працює на CentOS, Fedora та Gentoo. gyaresu успішно випробував його на Дебіані Ленні.

#!/bin/bash

get_distribution_type()
{
    local dtype
    # Assume unknown
    dtype="unknown"

    # First test against Fedora / RHEL / CentOS / generic Redhat derivative
    if [ -r /etc/rc.d/init.d/functions ]; then
        source /etc/rc.d/init.d/functions
        [ zz`type -t passed 2>/dev/null` == "zzfunction" ] && dtype="redhat"

    # Then test against SUSE (must be after Redhat,
    # I've seen rc.status on Ubuntu I think? TODO: Recheck that)
    elif [ -r /etc/rc.status ]; then
        source /etc/rc.status
        [ zz`type -t rc_reset 2>/dev/null` == "zzfunction" ] && dtype="suse"

    # Then test against Debian, Ubuntu and friends
    elif [ -r /lib/lsb/init-functions ]; then
        source /lib/lsb/init-functions
        [ zz`type -t log_begin_msg 2>/dev/null` == "zzfunction" ] && dtype="debian"

    # Then test against Gentoo
    elif [ -r /etc/init.d/functions.sh ]; then
        source /etc/init.d/functions.sh
        [ zz`type -t ebegin 2>/dev/null` == "zzfunction" ] && dtype="gentoo"

    # For Slackware we currently just test if /etc/slackware-version exists
    # and isn't empty (TODO: Find a better way :)
    elif [ -s /etc/slackware-version ]; then
        dtype="slackware"
    fi
    echo $dtype
}

Зауважте, що це, ймовірно, працює правильно лише в Bash. Ви можете переписати його для інших оболонок.

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


Концептуально, що це робиться, щоб:

  • Виберіть відомий, тип «загальної функції скрипта init». Вони залежать від розподілу. Якщо його не існує, перейдіть до наступної перевірки розповсюдження.
  • Перевірте існування певної, відомої для існування, часто використовуваної та малоймовірно перейменованої функції з цього основного сценарію. Ми робимо це за допомогою typeвбудованого Bash. type -tповертається, functionякщо цей символ є функцією. Ми додаємо zzдо результату, type -t 2>/dev/nullоскільки якщо ім'я не визначено, рядок виводу буде порожнім, і ми отримаємо синтаксичну помилку щодо відсутньої лівої руки до ==оператора. Якщо ім'я, яке ми щойно перевірили, не є функцією, переходите до наступної перевірки розповсюдження, інакше ми знайшли тип розподілу.
  • Нарешті, відлуньте тип розподілу, щоб функцію виводу можна було легко використовувати у блоці case .. esac.

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

source /path/to/this/script.sh
get_distribution_type

в баш-підказці.


Редагувати: Зверніть увагу, що цей скрипт не вимагає привілеїв root. Я закликаю вас не запускати це як root. Не повинні нічого шкодити, але в цьому немає потреби.


Знайдено посилання на відповідну публікацію списку розсилки в журналі CVS. Потрібно бути корисним для розгортання спагеті від сценарію init.


Я не дивився на те, чому він повертається до Debian Lenny (5.0).
Гарет

gyaresu, чи справді ви викликали функцію get_distribution_type? Я відредагував пост, щоб уточнити (див. Внизу.)
Mihai Limbăşan

@gyaresu: Якщо вищезгадане не було проблемою, можете спробувати замінити log_begin_msg у розділі Debian на log_warning_msg та повторити спробу? Можливо, неправильно зрозуміли ім’я функції. У будь-якому випадку, він мав би повернутись "невідомо", якби ця функція була не htere, але все ж.
Міхай Лімбашан

@Mihai Doh! Вибачте. Не правильно прочитав сценарій. Рано було, кави немає. Прошу вибачення. gyaresu @ debian: ~ / bin $ source server_version.sh gyaresu @ debian: ~ / bin $ get_distribution_type debian
Гарет

@gyaresu: Дякую! Це добре, має допомогти jldugger дізнатися, що він працює і на Debian :)
Mihai Limbăşan

17

Ви можете знайти версію ядра, запустивши uname -a, пошук дистрибутива залежить від дистрибутива.

На Ubuntu та деяких інших ОС можна запускати lsb_release -aчи читати / etc / lsb_release

Debian зберігає версію в / etc / debian_version


+1 для lsb_release (також працює на похідних Red Hat, якщо встановлений правильний пакет)
Josh Kelley

лише для опису 'lsb_release -ds'.
мерехтіння

6

Більшість дистрибуторів мають унікальний метод визначення конкретного розподілу.

Наприклад:

Redhat (And derivatives): /etc/redhat-release

SUSE: /etc/SUSE-release

Існує стандарт, відомий як Linux Standard Base або LSB . Він визначає, що має бути файл під назвою / etc / lsb-release або програма під назвою lsb_release, яка повторюватиме інформацію про ваш Linux-дистрибутив.

lsb_release -a

І звичайно, lsb_releaseне існує на CentOS 6.
Джастін


5

На додаток до інших відповідей: Якщо ви просто хочете проаналізувати один файл, більшість дистрибутивів персоналізують tty логін через / etc / issue, наприклад:

Ласкаво просимо до SUSE Linux Enterprise Server 10 SP2 (i586) - ядро ​​\ r (\ l).

І так, я знаю, що це неоптимально. :)


Це може бути неоптимальним, але він знаходиться там же.
Бред Гілберт

4

facter - це зручний інструмент для такого роду виявлення, хоча, ймовірно, використовується деякі з описаних вище методів і вимагає Ruby.


2

Все, що вам потрібно зробити - це набрати uname -aулюблену оболонку. Це дозволить роздрукувати ім'я та версію ядра.


2

Я виявив, що cat /etc/*release*майже завжди працює.


2

Я погоджуюся з Марком, Адамом та Міхай (не можу проголосувати через недостатню репутацію). Рішення, засновані на LSB та його відносних FHS , працюватимуть з більшістю дистрибутивів і, ймовірно, продовжать роботу в майбутньому. LSB і FHS - ваші друзі.


2

Ви також можете отримати версію до

cat /proc/version

о / р:

Версія Linux 2.6.17-13mdv (rtp@octopus.mandriva.com) (gcc версія 4.1.2 20070302 (попередня версія) (4.1.2-1mdv2007.1)) # 1 SMP Пт, 23 березня 19:03:31 UTC 2007


1

Версія linux - важке питання. Якщо ми розглянемо це вузько, у нас є версія ядра, яку ви можете отримати з " uname -r". Версія дистрибуції здебільшого не має значення. Деякі дистрибутиви є кращими (корпоративні дистрибутиви, такі як Redhat Enterprise Linux). Інші дистрибутиви, такі як Gentoo - це в основному рухомі цілі, які взагалі не мають розумної версії. Якщо вам потрібно робити речі на основі версії, перегляньте основні компоненти, що стосуються вас:

Component       Version command
glibc           /lib/libc.so.6
gcc             gcc --version
X               xdpyinfo
libX11          pkg-config --modversion x11
gtk+            pkg-config --modversion gtk+-2.0
qt-4            pkg-config --modversion QtCore

   etc...

1

Ви також можете перевірити меню Grub, зазвичай дає вам купу інформації про дистрибуцію / версію :-)


-1

FusionInventory - це полегшений інструмент інвентаризації між платформами, який може отримати цю інформацію в багатьох дистрибутивах Linux, а також на BSD, Windows, MacOS X та інших пристроях.

Якщо вони доступні, вони використовують lsb_release(як згадувалося кілька разів вище), але якщо ні, у них є дуже корисний список файлів та регулярних виразів для перевірки назви та версії дистрибутива: https://github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / FusionInventory / Agent / Task / Inventory / Input / Linux / Distro / NonLSB.pm # L16 .

Я б рекомендував використовувати FusionInventory для отримання цієї інформації, а не повторного доповнення власних сценаріїв за допомогою цієї логіки, оскільки їх спільнота підтримуватиме цю функціональність в актуальному стані. Ви можете або використовувати агент самостійно (він виводить файл XML / JSON, який легко проаналізувати), або з'єднати його з більш широким рішенням для управління машинами у вашій мережі, такими як GLPI або Рудер , залежно від ваших потреб.


Це було б хорошим рішенням, якби у нього не було зовнішніх залежностей модулів Perl
Буде Шеппард
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.