[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