有时,您的脚本需要在不同的Linux上表现不同。如何确定脚本运行在哪个Linux版本上?
有时,您的脚本需要在不同的Linux上表现不同。如何确定脚本运行在哪个Linux版本上?
Answers:
不要尝试根据发行版来确定您可以做什么和不能做什么,因为这是疯狂的原因(另请参见“用户代理检测”)。相反,请检测是否支持您要执行的操作,以及如何通过要使用的命令或文件位置来完成操作。
例如,如果要安装软件包,则可以通过检查dpkg或rpm是否存在来检测您是在Debian还是RedHat上(首先检查dpkg,因为Debian机器可以安装dpkg)。他们上的rpm命令...)。在此基础上,决定要做什么,而不仅仅是决定是Debian还是RedHat系统。这样,您将自动支持未明确编程的任何派生发行版。哦,如果您的程序包需要特定的依赖项,那么也请测试这些依赖项,并让用户知道它们的缺失。
另一个示例是摆弄网络接口。根据是否存在/ etc / network / interfaces文件或/ etc / sysconfig / network-scripts目录来确定要执行的操作,然后从那里开始。
是的,这是更多的工作,但是除非您要重现Web开发人员在过去十年或更长时间里犯下的所有错误,否则从一开始就将明智地做到这一点。
没有交叉分配的方式。然而:
- 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上运行良好。gyaresu在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中正常工作。您可以将其重写为其他shell。
话虽如此,您可能需要测试功能而不是发行版。我不再仅仅因为它已成为维护负担而使用它。依靠交叉分发工具和解决方案更加容易。
从概念上讲,它的作用是:
- 提取一个已知的“公共初始化脚本功能”类型的文件。这些是特定于发行版的。如果不存在,请跳至下一个分发检查。
- 检查该核心脚本中是否存在特定的,已知的,经常使用的且不太可能重命名的功能。我们使用
type
内置的Bash来做到这一点。type -t
返回function
该符号是否为函数。我们zz
把输出放在前面,type -t 2>/dev/null
因为如果未定义名称,则输出字符串将为空,并且会收到有关==
操作员缺少左手的语法错误。如果我们刚刚检查的名称不是函数,请跳至下一个分发检查,否则我们找到了分发类型。- 最后,回显分配类型,以便可以在esac块中轻松使用函数输出。
编辑,以防您尝试将其作为纯脚本运行:该脚本应该从其他脚本中获取或包含。如果按原样运行,它不会自行输出任何内容。要对其进行测试,请获取其源代码,然后调用该函数,例如:
source /path/to/this/script.sh
get_distribution_type
在bash提示下。
编辑:请注意,此脚本不需要root特权。我敦促您不要以root用户身份运行它。不应伤害任何事物,但没有必要。
在CVS日志中找到相关邮件列表帖子的链接。在展开初始化脚本意大利面条时应该很有用。
您可以通过运行找到内核版本uname -a
,查找发行版版本取决于发行版。
在Ubuntu和其他一些操作系统上,您可以运行lsb_release -a
或阅读/ etc / lsb_release
Debian将版本存储在/ etc / debian_version中
python -c 'import platform ; print platform.dist()[0]'
python -c 'import platform; print(platform.dist()[0])'
,因为这样,如果普通python默认为python3,它也可以工作。
您需要做的就是键入uname -a
您喜欢的shell。这将打印出内核名称和版本。
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...
FusionInventory是一种跨平台的轻量级清单工具,可以在许多Linux发行版上以及在BSD,Windows,MacOS X和其他unices上获得此信息。
如果可用,它们将使用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或Rudder等网络中的计算机。