有时你的脚本需要在不同的Linux上有不同的performance。 我怎样才能确定脚本运行在哪个版本的Linux上?
不要试图根据发行版做一些假设,就是说你可以做什么,不可以做什么,因为这种方式就是疯狂(参见“用户代理检测”)。 相反,检测是否支持您要执行的操作,以及您希望使用的任何命令或文件位置是如何完成的。
例如,如果你想安装一个软件包,你可以通过检查dpkg或rpm的存在来检测你是否在类似Debian的系统或类似RedHat的系统上(首先检查dpkg,因为Debian机器可以有在他们的rpm命令…)。 在此基础上做出决定,而不仅仅是Debian或RedHat系统。 这样,你将自动支持你没有明确编程的衍生发行版。哦,如果你的包需要特定的依赖关系,那么也testing这些,并让用户知道他们错过了什么。
另一个例子是摆弄networking接口。 根据是否有/ etc / network / interfaces文件或/ etc / sysconfig / network-scripts目录来确定要执行的操作,然后从那里进行操作。
是的,这是更多的工作,但除非你想重写networking开发者在过去十年甚至更长时间所犯的所有错误,否则你一定会从一开始就以一种聪明的方式来做到这一点。
没有交叉分配的方式。 然而:
- Redhat和朋友:testing/ etc / redhat-release,检查内容
- Debian:testing/ etc / debian_version,检查内容
- Mandriva和朋友们:testing/ etc / version,检查内容
- Slackware:testing/ etc / slackware-version,检查内容
等等一般来说,请检查/etc/*-release
和/etc/*-version
。
编辑:发现我的旧(1岁以上)bash脚本躺在我一定多年来拼凑在一起(它有一个令人印象深刻的CVS日志回6年)它可能无法正常工作,现在是,我可以不用费心寻找安装发行版来testing,但它应该为您提供一个很好的起点。 它在CentOS,Fedora和Gentoo上运行良好。 gyaresu在Debian Lenny上成功testing了它。
#!/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。
这就是说,你可能想testing的function,而不是分配。 我不再只是因为它成了维护的负担。 依靠交叉分配工具和解决scheme更容易。
从概念上讲,它所做的是:
- 拉入已知的“通用初始化脚本函数”types的文件。 这些是分发特定的。 如果不存在,请跳至下一次分发检查。
- 检查该核心脚本中是否存在特定的,已知的,经常使用的,不太可能被重命名的函数。 我们使用Bash内build
type
做到这一点。 如果该符号是一个函数,则type -t
返回函数。 我们在type -t 2>/dev/null
前面加上zz
,因为如果名称没有定义,那么输出string将是空的,我们会得到关于==
运算符缺less左手的语法错误。 如果我们刚刚检查的名称不是函数,则跳到下一次分发检查,否则我们find分发types。- 最后,回显分配types,这样可以方便地使用函数输出。esac块。
编辑万一你试图把它作为一个直接的脚本运行:这个脚本应该从其他脚本来源或包含。 如果按原样运行,它不会自行输出任何内容。 要testing它,请input它,然后调用该函数,例如:
source /path/to/this/script.sh get_distribution_type
在bash提示符下。
编辑:请注意,这个脚本不需要root权限。 我敦促你不要以root身份运行它。 不应该伤害任何东西,但是没有必要。
在CVS日志中find了相关邮件列表文章的链接。 在展开init脚本意大利面时应该很有用。
你可以通过运行uname -a
find内核版本,发现发行版本依赖于发行版。
在Ubuntu和其他一些操作系统上,你可以运行lsb_release -a
或者读取/ etc / lsb_release
Debian将版本存储在/ etc / debian_version中
大多数发行版都有确定特定发行的独特方法。
例如:
Redhat (And derivatives): /etc/redhat-release SUSE: /etc/SUSE-release
有一个标准在那里被称为Linux标准基地或LSB 。 它定义应该有一个名为/ etc / lsb-release的文件或一个名为lsb_release的程序,它会回显你的linux发行版的信息。
lsb_release -a
python -c 'import platform ; print platform.dist()[0]'
代码: http : //hg.python.org/cpython/file/2.7/Lib/platform.py
除了其他答案:如果你只是想parsing一个文件,大多数发行版通过/ etc / issue来个性化ttylogin,例如:
欢迎使用SUSE Linux Enterprise Server 10 SP2(i586) – Kernel \ r(\ l)。
是的,我知道这是不理想的。 🙂
facter是这种发现的便利工具,尽pipe它可能使用了上面详述的一些方法,并且需要Ruby。
所有你需要做的就是在你喜欢的shell中inputuname -a
。 这将打印出内核名称和版本。
我发现cat /etc/*release*
几乎总是有效的。
我同意马克,亚当和米海(因名誉不足而不能投票)。 基于LSB及其相关FHS的解决scheme将适用于大多数分销,并有可能在未来继续工作。 LSB和FHS是你的朋友。
你也可以通过获取版本
cat /proc/version
O / P:
Linux版本2.6.17-13mdv([email protected])(gcc version 4.1.2 20070302(prerelease)(4.1.2-1mdv2007.1))#1 SMP Fri Mar 23 19:03:31 UTC 2007
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...
你也可以查看Grub菜单,通常会给你一些发行版/版本信息:-)
FusionInventory是一个跨平台的轻量级清单工具,可以在许多Linux发行版上获取这些信息,但也可以在BSD,Windows,MacOS X和其他unices上获取。
如果可用的话,他们使用lsb_release
(如上面提到的几次),但是如果没有,他们有一个非常有用的文件列表和正则expression式来检查发行版名称和版本: https : //github.com/fusinv/fusioninventory-agent /blob/2.2.x/lib/FusionInventory/Agent/Task/Inventory/Input/Linux/Distro/NonLSB.pm#L16 。
我build议使用FusionInventory来获取这些信息,而不是用这个逻辑来重新实现自己的脚本,因为他们的社区会保持这个function是最新的。 您可以自行使用代理(输出一个容易parsing的XML / JSON文件),也可以将其与更广泛的解决scheme结合使用,以根据您的需要pipe理networking中的计算机(如GLPI或Rudder) 。