有时您的脚本需要在不同的 Linux 上有不同的行为。如何确定脚本在哪个版本的 Linux 上运行?
答案1
不要尝试根据发行版来假设您可以做什么和不能做什么,因为这样做很疯狂(另请参阅“用户代理检测”)。相反,检测您想要做的事情是否受支持,以及您想要使用的任何命令或文件位置如何完成它。
例如,如果您想要安装一个软件包,您可以通过检查是否存在 dpkg 或 rpm 来检测您是在 Debian 类系统上还是 RedHat 类系统上(首先检查 dpkg,因为 Debian 机器上可能有 rpm 命令...)。根据此信息来决定要做什么,而不仅仅是根据它是 Debian 还是 RedHat 系统。这样,您将自动支持您未明确编程的任何衍生发行版。哦,如果您的软件包需要特定的依赖项,那么也请测试这些依赖项并让用户知道他们缺少什么。
另一个例子是摆弄网络接口。根据是否存在 /etc/network/interfaces 文件或 /etc/sysconfig/network-scripts 目录来确定要做什么,然后从那里开始。
是的,这需要做更多的工作,但除非您想重犯 Web 开发人员在过去十年或更长时间里犯下的所有错误,否则您从一开始就应该以聪明的方式去做。
答案2
没有跨分销的方式。但是:
- 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 上运行良好。贾雷苏在 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
==
- 最后,回显分布类型,以便函数输出可轻松用于 case.. esac 块中。
如果您尝试将其作为直接脚本运行,请进行编辑:此脚本应该从其他脚本获取或包含。如果按原样运行它,它不会自行输出任何内容。要测试它,请获取它,然后调用该函数,例如:
source /path/to/this/script.sh
get_distribution_type
在 bash 提示符下。
编辑:请注意,此脚本不需要 root 权限。我建议您不要以 root 身份运行它。不会造成任何损害,但没有必要。
找到相关链接邮件列表帖子在 CVS 日志中。应该对解开 init 脚本意大利面条很有用。
答案3
您可以通过运行来找到内核版本uname -a
,查找发行版版本取决于发行版。
在 Ubuntu 和其他一些操作系统上,你可以运行lsb_release -a
或读取 /etc/lsb_release
Debian 将版本存储在 /etc/debian_version 中
答案4
python -c 'import platform ; print platform.dist()[0]'