我正在编写一个只应在RHEL6或RHEL7主机上运行的脚本。
我觉得这很容易。使用uname -r
,sed
和聪明的正则表达式。
好吧,我无法想出一个聪明的正则表达式:( ...
以下是我要做的事情的详细信息:
$ uname -r
3.10.0-123.20.1.el7.x86_64
$ uname -r | sed -e's/... clever stuff here .../\1/g'
7
这是我试过的,请不要笑:
$ uname -r | sed -e's/^.*\.el\(\d)\.*$/\1/g'
sed: -e expression #1, char 23: Unmatched ( or \(
$ uname -r | sed -e's/^.*\.el\{1}(\d)\.*$/\1/g'
sed: -e expression #1, char 26: Unmatched \{
$ uname -r | sed -e's/^.*\.el{1}\(\d\)\.*$/\1/g'
3.10.0-123.20.1.el7.x86_64
$ uname -r | sed -e's/^.*\.el\(\d\)\.*$/\1/g'
3.10.0-123.20.1.el7.x86_64
$ uname -r | sed -e's/^.*\.el\(\.\)\.*$/\1/g'
3.10.0-123.20.1.el7.x86_64
$ uname -r | sed 's/\([0-9]\+\.[0-9]\+\)\..*/\1/'
3.10
$ uname -r | sed 's/el+\.[0-9]\+\)\..*/\1/'
sed: -e expression #1, char 24: Unmatched ) or \)
$ uname -r | sed 's/el+\.\([0-9]\+\)\..*/\1/'
3.10.0-123.20.1.el7.x86_64
$ uname -r | sed 's/el+\.\([0-9]\)\..*/\1/'
3.10.0-123.20.1.el7.x86_64
$ uname -r | sed 's/^.*\.el+\.\([0-9]\)\..*/\1/'
3.10.0-123.20.1.el7.x86_64
答案 0 :(得分:3)
解析内核版本以找出RHEL版本是一个糟糕的想法,因为如果发布的内核不遵循相同的命名方案呢?虽然它现在可能有用,但它是一个脆弱的解决方案。
有几种方法可以确定当前的RHEL版本。
最容易的,正如格伦杰克曼在评论中所建议的,可能是要解析/etc/redhat-release
,看起来像(对于RHEL 7):
Red Hat Enterprise Linux Server release 7.2 (Maipo)
对于RHEL 6:
Red Hat Enterprise Linux Server release 6.5 (Santiago)
稍微好一点的方法是查询已安装的redhat-release
包的版本:
$ rpm -q --qf '%{VERSION}\n' -f /etc/redhat-release
7.2
这说“告诉我拥有/etc/redhat-release
”的软件包的版本。上面的例子是在RHEL7下运行的;在RHEL6 yieilds下运行时也是如此:
$ rpm -q --qf '%{VERSION}\n' -f /etc/redhat-release
6Server
答案 1 :(得分:2)
嗯,你有几种选择。
uname -r | sed 's/^.*\.el\([0-9]*\)\..*$/\1/'
应该这样做。
那说"寻找一段时间后跟着' el'后跟一些数字后跟一段时间。用这些数字替换整行。"
让我们回顾你的尝试。大多数情况下,您需要了解正则表达式语法的不同风格之间的区别; sed不是Perl。
$ uname -r | sed -e's/^.*\.el\(\d)\.*$/\1/g'
sed: -e expression #1, char 23: Unmatched ( or \(
$ uname -r | sed -e's/^.*\.el\{1}(\d)\.*$/\1/g'
sed: -e expression #1, char 26: Unmatched \{
在这两种方法中,你使用了一个背面的开口支架,但试图在没有反斜杠的情况下关闭它。在sed中,\(
由\)
关闭,\{
由\}
关闭。
$ uname -r | sed -e's/^.*\.el{1}\(\d\)\.*$/\1/g'
3.10.0-123.20.1.el7.x86_64
{1}
是字面意思 - 因此您需要在文字花括号中查找字面数字1。由于它没有找到任何这样的东西,它没有做任何改变,线条没有改变。
$ uname -r | sed -e's/^.*\.el\(\d\)\.*$/\1/g'
3.10.0-123.20.1.el7.x86_64
如果默认情况sed
理解\d
,这几乎可以正常工作。但是你有\.*
的事实是混乱的 - 它只匹配0或更多的句号。你想要\..*
- 一个文字句号后跟任意数量的字符。此外,默认情况下,sed 并不了解\d
。你需要[0-9]
。
$ uname -r | sed -e's/^.*\.el\(\.\)\.*$/\1/g'
3.10.0-123.20.1.el7.x86_64
括号内的点前面的反斜杠意味着您正在寻找文字句点而不是任何字符。而且你再次拥有\.*
。
$ uname -r | sed 's/\([0-9]\+\.[0-9]\+\)\..*/\1/'
3.10
这完全符合你的要求..你在这里找什么?
$ uname -r | sed 's/el+\.[0-9]\+\)\..*/\1/'
sed: -e expression #1, char 24: Unmatched ) or \)
您有\)
但没有\(
。
$ uname -r | sed 's/el+\.\([0-9]\+\)\..*/\1/'
3.10.0-123.20.1.el7.x86_64
$ uname -r | sed 's/el+\.\([0-9]\)\..*/\1/'
3.10.0-123.20.1.el7.x86_64
$ uname -r | sed 's/^.*\.el+\.\([0-9]\)\..*/\1/'
3.10.0-123.20.1.el7.x86_64
+
匹配文字加号。
答案 2 :(得分:2)
试试这个:
$ uname -r | sed 's/.*el\([0-9]\).*/\1/g'
或
$ uname -r | sed -r 's/.*el([0-9]).*/\1/g'