Иногда ваши скрипты должны вести себя по-разному на разных Linux. Как я могу определить, на какой версии Linux работает скрипт?
Иногда ваши скрипты должны вести себя по-разному на разных Linux. Как я могу определить, на какой версии Linux работает скрипт?
Ответы:
Не пытайтесь делать предположения, основанные на дистрибутиве, относительно того, что вы можете и не можете сделать, потому что в этом и заключается безумие (см. Также «Обнаружение агента пользователя»). Вместо этого определите, поддерживается ли то, что вы хотите сделать, и как это делается с помощью любой команды или местоположения файла, которое вы хотите использовать.
Например, если вы хотите установить пакет, вы можете определить, находитесь ли вы в Debian-подобной системе или в RedHat-подобной системе, проверив наличие dpkg или rpm (сначала проверьте dpkg, потому что машины Debian могут иметь команда rpm на них ...). Примите решение о том, что делать, основываясь на этом, а не только на том, является ли это системой Debian или RedHat. Таким образом, вы автоматически будете поддерживать любые производные дистрибутивы, в которых вы явно не программировали. О, и если вашему пакету требуются определенные зависимости, то тоже проверьте их и сообщите пользователю, что им не хватает.
Другой пример - возиться с сетевыми интерфейсами. Подумайте, что делать, основываясь на том, есть ли файл / etc / network / interfaces или каталог / etc / sysconfig / network-scripts, и перейдите оттуда.
Да, это больше работы, но если вы не хотите исправить все ошибки, которые веб-разработчики допустили за последнее десятилетие или более, вы сделаете это с умом с самого начала.
Там нет пути кросс-распределения. Тем не мение:
- Redhat и друзья: проверить
/etc/redhat-release
, проверить содержимое- Debian: проверить
/etc/debian_version
, проверить содержимое- Мандрива и друзья: проверить
/etc/version
, проверить содержание- Slackware: проверить
/etc/slackware-version
, проверить содержимое
И т.д. Вообще говоря, проверьте /etc/*-release
и /etc/*-version
.
Редактировать: Нашел старый (1+ лет) мой скрипт bash, который лежал без дела, и который я, должно быть, выковывал вместе на протяжении многих лет (он имеет впечатляющий журнал CVS за 6 лет). Он может больше не работать должным образом, как есть, и я могу Не беспокойтесь о том, чтобы найти установленные дистрибутивы для тестирования, но это должно послужить хорошей отправной точкой. Он отлично работает на CentOS, Fedora и Gentoo. gyaresu успешно проверил его на Debian Lenny.
#!/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. Вы могли бы переписать его для других оболочек.
Тем не менее, вы можете проверить возможности, а не дистрибутивы. Я больше этим не пользуюсь просто потому, что это стало бременем для обслуживания. Проще полагаться на кросс-дистрибутивные инструменты и решения.
Концептуально, что он делает, по порядку:
- Извлеките файл с известным типом «общая функция сценария инициализации». Это зависит от распределения. Если он не существует, перейдите к следующей проверке распространения.
- Проверьте наличие определенной, известной, часто используемой и вряд ли переименованной функции из этого основного сценария. Мы делаем это с помощью
type
встроенного Bash.type -t
возвращает,function
если этот символ является функцией. Мы подходимzz
к выводу из,type -t 2>/dev/null
потому что, если имя не определено, выходная строка будет пустой, и мы получим синтаксическую ошибку об отсутствующей левой руке==
оператора. Если имя, которое мы только что проверили, не является функцией, перейдите к следующей проверке распространения, в противном случае мы нашли тип распространения.- Наконец, укажите тип распределения, чтобы выходные данные функции можно было легко использовать в блоке case ... esac.
Отредактируйте, если вы пытаетесь запустить его как прямой сценарий: предполагается, что этот сценарий получен из других сценариев или включен в него. Он ничего не выводит сам по себе, если вы запускаете его как есть. Чтобы проверить это, создайте его, а затем вызовите функцию, например:
source /path/to/this/script.sh
get_distribution_type
в приглашении bash.
Изменить: Обратите внимание, что этот скрипт не требует привилегий root. Я призываю вас не запускать его как root. Ничего не должно навредить, но в этом нет необходимости.
Нашел ссылку на соответствующую запись в списке рассылки в журнале CVS. Должно быть полезно при распаковке спагетти сценария инициализации.
Вы можете найти версию ядра, запустив ее uname -a
, обнаружив, что версия дистрибутива зависит от дистрибутива.
В Ubuntu и некоторых других ОС вы можете запустить lsb_release -a
или прочитать / etc / lsb_release
Debian хранит версию в / etc / debian_version
Большинство дистрибутивов имеют уникальный метод определения конкретного распределения.
Например:
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.
python -c 'import platform ; print platform.dist()[0]'
python -c 'import platform; print(platform.dist()[0])'
, потому что таким образом это также работает, если обычный питон по умолчанию равен python3.
В дополнение к другим ответам: Если вы просто хотите проанализировать один файл, большинство дистрибутивов персонализируют логин tty через / etc / issue, например:
Добро пожаловать в SUSE Linux Enterprise Server 10 SP2 (i586) - Ядро \ r (\ l).
И да, я знаю, что это неоптимально. :)
Все, что вам нужно сделать, это набрать uname -a
в вашей любимой оболочке. Это выведет имя и версию ядра.
Я согласен с Марком, Адамом и Михаем (не могу голосовать из-за недостаточной репутации). Решения, основанные на LSB и его относительной FHS, будут работать с большинством дистрибутивов и, вероятно, продолжат работать в будущем. LSB и FHS - твои друзья.
Версия 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...
Вы также можете проверить меню Grub, которое обычно дает вам кучу информации о дистрибутиве / версии :-)
FusionInventory - это кроссплатформенный легкий инструмент для инвентаризации, который может получить эту информацию во многих дистрибутивах Linux, а также на BSD, Windows, MacOS X и других устройствах.
Если доступно, они используют lsb_release
(как упоминалось несколько раз выше), но если нет, у них есть очень полезный список файлов и регулярных выражений для проверки имени и версии дистрибутива: https://github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / FusionInventory / Агент / Задача / Инвентаризация / Входные данные / Linux / Distro / NonLSB.pm # L16 .
Я бы порекомендовал использовать саму FusionInventory для получения этой информации, а не переопределять собственные сценарии с помощью этой логики, поскольку их сообщество будет поддерживать эту функциональность в актуальном состоянии. Вы можете использовать агент самостоятельно (он выводит файл XML / JSON, который легко анализировать) или объединить его с более широким решением для управления машинами в вашей сети, такими как GLPI или Rudder , в зависимости от ваших потребностей.