Вопрос или проблема
Я изучаю основы скриптинга и пытаюсь написать скрипт, который определяет, на каком дистром Linux он запущен. Я придумал простую версию, как показано ниже:
#!/bin/sh
which yum >/dev/null && { echo "Fedora"; exit 0; }
which zypper >/dev/null && { echo "Suse"; exit 0; }
which apt-get >/dev/null && { echo "На основе Debian"; }
Существует ли более элегантный способ определить, на каком дистрибутиве Linux я работаю?
Можно ли включить Unix – или сделать это универсальным для любых Xnix?
Большое спасибо.
Правка: это не дубликат Как определить используемый дистрибутив Linux? по следующим причинам:
Для Ubuntu, cat /etc/lsb-release
работает отлично, для RedHat – нет.
ls /etc/*release
работает, но он показывает три папки. cat /proc/version
выглядит многообещающе, но требует немного магии с regex.
На современных Fedora и Debian (а также на Alma Linux, Alpine, Arch, CentOS Stream, Mageia, openSUSE, Red Hat Enterprise Linux, SUSE Linux Enterprise Server, Ubuntu и других) самым простым способом является просмотр /etc/os-release
или выполнение команды hostnamectl status
.
В скрипте вы можете просто сделать
#!/bin/sh
source /etc/os-release
echo $PRETTY_NAME
Конечно, если вам нужно идентифицировать очень старые версии или необычные дистрибутивы, вы можете начать с вышеуказанного, но если /etc/os-release
не существует, переходите к дальнейшим эвристикам.
Обратите внимание, что если вы хотите, чтобы ваш скрипт работал с результатом (например, для перехода к использованию различных команд установки), вы должны использовать $ID
и, возможно, $VARIANT_ID
вместо $PRETTY_NAME
, который предназначен для отображения.
Я попробовал с:
cat /etc/*release | grep "^ID="
И с Ubuntu и CentOS это тоже сработало.
Я поделюсь кодом скрипта, который я делаю, который поддерживает более 12 различных систем Linux и определяет, является ли система на базе ARM. В начале есть массив, в который вы должны поместить поддерживаемые вами дистрибутивы Linux. Он имеет две фазы. Первая фаза – это поиск слов в массиве по выводу команды uname. А вторая фаза – это проверка существующих специальных файлов в /etc, которые зависят от дистрибутива.
#!/bin/bash
is_arm=0
#Переменные дистрибутивов
known_compatible_distros=(
"Wifislax"
"Kali"
"Parrot"
"Backbox"
"Blackarch"
"Cyborg"
"Ubuntu"
"Debian"
"SuSE"
"CentOS"
"Gentoo"
"Fedora"
"Red Hat"
"Arch"
"OpenMandriva"
)
known_arm_compatible_distros=(
"Raspbian"
"Parrot arm"
"Kali arm"
)
#Первая фаза обнаружения дистрибутива Linux на основе вывода команды uname
function detect_distro_phase1() {
for i in "${known_compatible_distros[@]}"; do
uname -a | grep "${i}" -i > /dev/null
if [ "$?" = "0" ]; then
distro="${i^}"
break
fi
done
}
#Вторая фаза обнаружения дистрибутива Linux на основе архитектуры и файлов версии
function detect_distro_phase2() {
if [ "${distro}" = "Неизвестный Linux" ]; then
if [ -f ${osversionfile_dir}"centos-release" ]; then
distro="CentOS"
elif [ -f ${osversionfile_dir}"fedora-release" ]; then
distro="Fedora"
elif [ -f ${osversionfile_dir}"gentoo-release" ]; then
distro="Gentoo"
elif [ -f ${osversionfile_dir}"openmandriva-release" ]; then
distro="OpenMandriva"
elif [ -f ${osversionfile_dir}"redhat-release" ]; then
distro="Red Hat"
elif [ -f ${osversionfile_dir}"SuSE-release" ]; then
distro="SuSE"
elif [ -f ${osversionfile_dir}"debian_version" ]; then
distro="Debian"
if [ -f ${osversionfile_dir}"os-release" ]; then
extra_os_info=$(cat < ${osversionfile_dir}"os-release" | grep "PRETTY_NAME")
if [[ "${extra_os_info}" =~ Raspbian ]]; then
distro="Raspbian"
is_arm=1
elif [[ "${extra_os_info}" =~ Parrot ]]; then
distro="Parrot arm"
is_arm=1
fi
fi
fi
fi
detect_arm_architecture
}
#Обнаружение архитектуры ARM на системе
function detect_arm_architecture() {
distro_already_known=0
uname -m | grep -i "arm" > /dev/null
if [[ "$?" = "0" ]] && [[ "${distro}" != "Неизвестный Linux" ]]; then
for item in "${known_arm_compatible_distros[@]}"; do
if [ "${distro}" = "${item}" ]; then
distro_already_known=1
fi
done
if [ ${distro_already_known} -eq 0 ]; then
distro="${distro} arm"
is_arm=1
fi
fi
}
detect_distro_phase1
detect_distro_phase2
echo "${distro}"
echo "${is_arm}"
Конечно, это можно улучшить… возможно, заменить цепочку “elif” на switch или что-то подобное… но это полностью рабочий вариант. Надеюсь, это поможет вам.
Итак, я застрял на этом, и после дня копания нашел это:
http://linuxmafia.com/faq/Admin/release-files.html
Затем еще один день работы/объединения и тестирования привел к следующему скрипту, который фактически был протестирован на
- Solaris
- RedHat
- Ubuntu
- SuSe
Если кто-то знает, как проверить другие дистрибутивы, буду признателен.
#!/bin/sh
# Определяет, какая ОС и если это Linux, то определяет, какой дистрибутив Linux.
# из http://linuxmafia.com/faq/Admin/release-files.html
#
OS=`uname -s`
REV=`uname -r`
MACH=`uname -m`
GetVersionFromFile()
{
VERSION=`cat $1 | tr "\n" ' ' | sed s/.*VERSION.*=\ // `
}
if [ "${OS}" = "Darwin" ]; then
OIFS="$IFS"
IFS=$'\n'
set `sw_vers` > /dev/null
DIST=`echo $1 | tr "\n" ' ' | sed 's/ProductName:[ ]*//'`
VERSION=`echo $2 | tr "\n" ' ' | sed 's/ProductVersion:[ ]*//'`
BUILD=`echo $3 | tr "\n" ' ' | sed 's/BuildVersion:[ ]*//'`
OSSTR="${OS} ${DIST} ${REV}(СОРРИ_БЕЗ_ПСЕВДОИМЕНИЯ ${BUILD} ${MACH})"
IFS="$OIFS"
elif [ "${OS}" = "SunOS" ] ; then
OS=Solaris
ARCH=`uname -p`
OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
elif [ "${OS}" = "AIX" ] ; then
OSSTR="${OS} `oslevel` (`oslevel -r`)"
elif [ "${OS}" = "Linux" ] ; then
KERNEL=`uname -r`
if [ -f /etc/redhat-release ] ; then
DIST='RedHat'
PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
elif [ -f /etc/SuSE-release ] ; then
DIST=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
elif [ -f /etc/mandrake-release ] ; then
DIST='Mandrake'
PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
elif [ -f /etc/debian_version ] ; then
DIST="Debian `cat /etc/debian_version`"
REV=""
elif [ -f /etc/UnitedLinux-release ] ; then
DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
fi
OSSTR="${OS} ${DIST} ${REV}(${PSUEDONAME} ${KERNEL} ${MACH})"
fi
echo ${OSSTR}
Ответ или решение
Для определения дистрибутива Linux (в частности, Fedora или Debian) с помощью shell-скрипта, можно использовать файл /etc/os-release
, который является стандартом для большинства современных дистрибутивов. Этот файл содержит переменные, которые описывают характеристики операционной системы.
Вот улучшенная версия скрипта, которая поддерживает большинство дистрибутивов Linux и использует содержимое файла /etc/os-release
для точного определения дистрибутива. Если файл не найден, скрипт также будет искать другие файлы, специфичные для определённых дистрибутивов.
#!/bin/bash
# Функция для определения дистрибутива
detect_distro() {
# Проверяем, существует ли файл /etc/os-release
if [[ -f /etc/os-release ]]; then
# Загружаем переменные из os-release
source /etc/os-release
case "$ID" in
fedora)
echo "Вы используете дистрибутив Fedora."
;;
debian)
echo "Вы используете дистрибутив Debian."
;;
ubuntu)
echo "Вы используете дистрибутив Ubuntu."
;;
centos)
echo "Вы используете дистрибутив CentOS."
;;
arch)
echo "Вы используете дистрибутив Arch Linux."
;;
*)
echo "Неизвестный дистрибутив: $ID."
;;
esac
else
echo "Файл /etc/os-release не найден. Пожалуйста, проверьте систему."
# Дальнейшая логика в случае отсутствия os-release
if [[ -f /etc/fedora-release ]]; then
echo "Вы используете дистрибутив Fedora."
elif [[ -f /etc/debian_version ]]; then
echo "Вы используете дистрибутив Debian."
elif [[ -f /etc/redhat-release ]]; then
echo "Вы используете дистрибутив Red Hat."
else
echo "Не удалось определить дистрибутив."
fi
fi
}
# Запускаем функцию определения дистрибутива
detect_distro
Пояснения к коду:
-
Проверка наличия файла /etc/os-release:
- Если файл существует, мы загружаем переменные с помощью
source
, что позволит нам использовать такие переменные, как$ID
для определения дистрибутива.
- Если файл существует, мы загружаем переменные с помощью
-
Использование
case
для определения дистрибутива:- Скрипт проверяет значение переменной
$ID
и печатает соответствующее сообщение.
- Скрипт проверяет значение переменной
-
Обработка отсутствия файла /etc/os-release:
- Если файл не найден, выполняется резервная проверка для специфических файлов дистрибутивов, таких как
/etc/fedora-release
и/etc/debian_version
, чтобы попытаться определить дистрибутив.
- Если файл не найден, выполняется резервная проверка для специфических файлов дистрибутивов, таких как
Заключение:
Этот скрипт поможет вам эффективно определить, запущен ли на вашей системе дистрибутив Fedora или Debian, а также другие дистрибутивы Linux. Он является более элегантным и поддерживает стандартный способ идентификации, что делает его более надежным по сравнению с проверками на наличие установочных менеджеров, таких как yum
или apt-get
.