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