[devel] os-release / lsb_release / VENDOR-release
Leonid Krivoshein
klark.devel на gmail.com
Вт Июн 4 03:34:26 MSK 2019
Всем привет!
Три вопроса к знатокам по методике определения Linux-дистрибутива, в
котором сейчас работает скрипт:
1) Это правда, что LSB-метод (lsb_release) не так широко распространён и
теперь уступает freedesktop'ному парсингу файла /etc/os-release? Критика
LSB в этой рассылке уже имела место несколько лет назад. Но альтернатив
тогда не предлагалось, де-факто стандарт нами не поддерживается (пакет
отсутствует в системе сразу после установки, на него нет зависимости в
basesystem/interactivesystem).
2) Как вы считаете, какой идентификатор (ID, DISTRIB_ID) должен быть у
наших систем -- "alt" или "altlinux"? Дело в том, что LSB считает нас
как "alt". Тогда как два других метода -- "altlinux". Пояснение в
прилагаемом скрипте.
3) Если исключить экзотику, типа разбора /proc/version или имени файла
ядра, есть ли хорошие примеры кода, надёжно определяющего текущий
дистрибутив Linux?
--
Best regards,
Leonid Krivoshein.
----------- следующая часть -----------
#!/bin/sh -efu
### This file is covered by the GNU General Public License
### version 2 or later.
###
### Copyright (C) 2019, ALT Linux Team
### Author: Leonid Krivoshein <klark на altlinux.org>
### Linux distribution detector
detect_linux_distro() {
local a= b= c= filename= idvar="$1"
local p= namevar="${2-}" rootfs="${3-}"
if [ "${__deploy_detect_linux_distro_included-}" != "2" ]; then
__deploy_detect_linux_distro_included=2
# parse single /etc/<RELEASE> file ($p)
# to DISTRO ID ($a) and DESCRIPTION ($b)
#
__parse_linux_release_file() {
if grep -qE ^PRETTY_NAME= "$p"; then
b="$(grep -sE ^PRETTY_NAME= "$p")"
b="$(unquote "${b:12}")"
elif grep -qE ^NAME= "$p" && grep -qE ^VERSION= "$p"; then
b="$(grep -sE ^NAME= "$p")"
b="$(unquote "${b:5}")"
if [ -n "$b" ]; then
c="$(grep -sE ^VERSION= "$p")"
c="$(unquote "${c:8}")"
[ -z "$c" ] || b="$b $c"
fi
fi
[ -n "$b" ] || return 0
if grep -qE ^ID= "$p"; then
a="$(grep -sE ^ID= "$p")"
a="$(unquote "${a:3}")"
elif grep -qE ^NAME= "$p"; then
a="$(grep -sE ^NAME= "$p")"; a="$(unquote "${a:5}")"
a="$(echo "${a% *}" |tr '[[:upper:]]' '[[:lower:]]')"
fi
[ -n "$a" ] || b=
}
# modern freedesktop.org standard
__detect_distro_by_os_release() {
for filename in /etc/os-release \
/lib/os-release \
/usr/lib/os-release
do
p="$rootfs$filename"
[ -r "$p" ] || continue
__parse_linux_release_file
[ -z "$a" ] || return 0
done
return 1
}
# also well-known, but not very common and
# sluggishly supported "Linux Standard Base"
# lsb_release command or /etc/lsb-release file
# (Chakra, IYCC, Arch Linux, Linux Mint, Ubuntu,
# Elementary OS, Manjaro Linux, etc...)
#
__detect_distro_by_lsb_release() {
[ -n "$rootfs" ] && c="" ||
c="$(command -v lsb_release 2>/dev/null ||:)"
if [ -x "$c" ]; then
a="$($c -si 2>/dev/null |
tr '[[:upper:]]' '[[:lower:]]')"
a="$(unquote "$a")"
if [ -n "$a" ]; then
b="$($c -sd 2>/dev/null ||:)"
b="$(unquote "$b")"
[ -n "$b" ] && return 0 || a=
fi
fi
p="$rootfs/etc/lsb-release"
[ -r "$p" ] || return 1
grep -qE ^DISTRIB_ID= "$p" || return 1
grep -qE ^DISTRIB_DESCRIPTION= "$p" || return 1
b="$(grep -sE ^DISTRIB_DESCRIPTION= "$p")"
b="$(unquote "${b:20}")"
[ -n "$b" ] || return 1
a="$(grep -sE ^DISTRIB_ID= "$p" |
tr '[[:upper:]]' '[[:lower:]]')"
a="$(unquote "${a:11}")"
[ -n "$a" ] && return 0 || b=
return 1
}
# fallback to the old detection method: please,
# don't check /etc/os-release and /etc/lsb-release
# files here, add your distro-specific file names,
# if necessary, but only by single name per line
#
__detect_distro_by_release_files() {
[ -n "$rootfs" ] && c="" ||
c="$(command -v hostnamectl 2>/dev/null ||:)"
[ ! -x "$c" ] || c="$($c 2>/dev/null |
grep -i 'operating system:' |
sed 's,^.*\: ,,')"
for filename in \
alpine-release \
altlinux-release \
annvix-release \
arch-release \
arklinux-release \
aurox-release \
blackcat-release \
cobalt-release \
conectiva-release \
eos-version \
gentoo-release \
hlfs-release \
hlfs_version \
immunix-release \
knoppix_version \
lfs-release \
lfs_version \
linuxppc-release \
mageia-release \
mandrake-release \
mandriva-release \
mandakelinux-release \
mklinux-release \
nld-release \
openwrt_version \
pld-release \
rubix-version \
slackware-version \
slackware-release \
e-smith-release \
sun-release \
SuSE-release \
novell-release \
sles-release \
system-release \
tinysofa-release \
trustix-release \
trustix-version \
turbolinux-release \
ultrapenguin-release \
UnitedLinux-release \
va-release \
yellowdog-release \
fedora-release \
redhat-release \
redhat_version \
debian_version \
debian_release
do
p="$rootfs/etc/$filename"
[ -r "$p" ] || continue
a="$(echo "$filename" |
sed -re 's,[_\-](release|version)$,,' |
tr '[[:upper:]]' '[[:lower:]]')"
b="$(head -n1 "$p")"
case "$a" in
system) a="amazon";;
debian) b="Debian $b";;
esac
[ -n "$b" ] || b=c
[ -n "$b" ] || [ -z "$namevar" ] || return 1
return 0
done
# Special case for Synology
# /etc/synoinfo.conf
# ToDo: ...
# Special case for Solaris SPARC and Sundry Linux
# /etc/release
# ToDo: ...
# Special case for NixOS
# /etc/NIXOS
# ToDo: ...
return 1
}
fi # __deploy_detect_linux_distro_included
__detect_distro_by_os_release ||
__detect_distro_by_lsb_release ||
__detect_distro_by_release_files ||:
# Replaces
case "$a" in
altlinux) a="alt";;
eos) a="freeeos";;
e-smith) a="esmith";;
mandakelinux) a="mandrake";;
nld) a="suse";;
novell) a="suse";;
sles) a="suse";;
unitedlinux) a="united";;
va) a="rhvale";;
esac
[ -z "$namevar" ] ||
eval "$namevar=\"${b:-Unknown Linux}\""
eval "$idvar=\"${a:-unknown}\""
}
Подробная информация о списке рассылки Devel