我正在学习脚本编写的基础知识,并尝试编写一个脚本来决定该脚本在哪种 Linux 上运行。我想出了一个简单的版本,如下所示:
#!/bin/sh
which yum >/dev/null && { echo Fedora flavour; exit 0; }
which zypper >/dev/null && { echo Suse of sorts; exit 0; }
which apt-get >/dev/null && { echo Debian based; }
有没有更优雅的方式来决定我运行的 Linux 版本?有没有办法包含 Unix - 或者让它成为任何类型的 Xnix 的通用版本?
多谢。
编辑:这不是重复的如何识别正在使用的 Linux 发行版?原因如下:对于 Ubuntu 来说,cat /etc/lsb-release
它非常有效;但对于 RedHat 来说,它却不行。它
ls /etc/*release
有效果,但是它列出了三个文件夹。cat /proc/version
看起来很有希望,但需要一些正则表达式魔法。
答案1
在现代 Fedora 和 Debian(以及 Arch、CentOS、CoreOS、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
当然,如果您还需要识别旧版本或非 systemd 发行版,您可以简单地从上述方法开始,但如果/etc/os-release
不存在,则跳转到进一步的启发式方法。
看检测 Linux 发行版名称和版本有关更多信息,请参阅 Stack Overflow 文档。
答案2
我尝试过:
cat /etc/*release | grep "^ID="
我也在 Ubuntu 和 Centos 上得到了它。
答案3
我将分享我正在编写的一个脚本的代码,该脚本支持超过 12 种不同的 Linux 系统并检测系统是否基于 Arm。一开始有一个数组,您必须在其中放置您支持的 Linux。它有两个阶段。第一个阶段是根据 uname 命令的输出在数组中搜索单词。第二个阶段是检查 /etc 中是否存在依赖于发行版的特殊内容。
#!/bin/bash
is_arm=0
#Distros vars
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"
)
#First phase of Linux distro detection based on uname output
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
}
#Second phase of Linux distro detection based on architecture and version file
function detect_distro_phase2() {
if [ "${distro}" = "Unknown 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
}
#Detect if arm architecture is present on system
function detect_arm_architecture() {
distro_already_known=0
uname -m | grep -i "arm" > /dev/null
if [[ "$?" = "0" ]] && [[ "${distro}" != "Unknown 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”链更改为案例或类似的东西...但这完全有效。我希望它对你有帮助。
答案4
因此,我对此感到困惑,经过一天的挖掘后发现了这一点: http://linuxmafia.com/faq/Admin/release-files.html
然后又经过一天的工作/合并和测试,得到了以下脚本,该脚本实际上已经过测试运行
- 索拉里斯
- 红帽
- Ubuntu
- 苏瑟
如果你们有办法检查其他发行版,我将不胜感激。
#!/bin/sh
# Detects which OS and if it is Linux then it will detect which Linux
# Distribution.
# from 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}(SORRY_NO_PSEUDONAME ${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}