从内核提取次要版本到 bash 变量
Extract minor version from kernel to bash variable
我是新手bash,正在写一个脚本,需要比较内核的次要版本,看是否大于等于10,否则退出。目前我有这样的东西:
KERNEL=$(uname -r)
declare -i MINOR_VERSION=$(echo $KERNEL | cut -c 3-4)
if [ "10" -gt "$MINOR_VERSION"]; then exit 0; fi
这是错误的代码,如果次要版本 < 10 则不起作用,因为我正在使用 cut 并且取决于它是两位数。我可能需要的是使用点来解析次要版本的东西。
示例:
$ uname -r
3.4.0-60-generic
$ MNR_VAR=<awesome bash code, with cut or sed or something>
$ echo $MNR_VAR
4
我一直在阅读 cut
和 sed
文档,但只是阅读起来很慢。我将不胜感激!
TL;DR - 寻找 bash 命令,该命令将提取变量中前两个点包围的 int
。 "3.13.0.x" returns '13', "3.2.0.x" returns '2' 等
编辑:
对于那些好奇的人,下面是一些答案。
uname -r | cut -d '.' -f2
uname -r | awk -F . '{print }'
kernel="$(uname -r)" | tmp="${kernel#*.}" | minor="${tmp%%.*}" | echo "$minor"
问题是您正在使用 -c
到 cut
。不要那样做。
使用 -f
和 -d
标志来控制要输出的分隔符和字段。
或使用awk -F . '{print }' <<< "$(uname -r)"
.
或使用 IFS=. read -r _ minor _rest <<< "$(uname -r)"; echo "$minor"
(其优点是不使用任何外部实用程序)。
<<< "$(uname -r)"
的用法是 bash 特定的(我相信)但避免了对管道 (|
) 和它的子 shell 的需要涉及。
纯bash:
#!/bin/bash
ker="$(uname -r)"
minker="${ker#*.}"
minker="${minker%%.*}"
echo "$minker"
"${ker#*.}"
是$ker
中第一个.
匹配之后的字符串。因此
$minker
从 3.13.0-generic...
变为 13.0-generic...
"${minker%%.*}"
是 $minker
中 .
及其后的所有匹配项(从右开始)剪切后留下的字符串。因此 $minker
从 13.0-generic...
变为 13
See the Bash Parameter Expansion Manual for more info
使用 Bash 正则表达式:
#!/bin/bash
regex='([0-9]+)\.([0-9]+)'
[[ $(uname -r) =~ $regex ]]
echo ${BASH_REMATCH[2]}
仅提取次要版本并将其与某些内容进行比较是有风险的,因为主要版本号也可能发生变化...
我通常更喜欢用零填充数字,这样可以使用简单的字符串比较轻松地比较它们。
kernel_version=$(uname -r | sed -r 's/([0-9]+)/0000/g; s/0*([0-9]{4})//g') # gives 0003.0004.0000-0060-generic
if [[ "$kernel_version" < "0003.0010" ]]; then exit 0; fi
我是新手bash,正在写一个脚本,需要比较内核的次要版本,看是否大于等于10,否则退出。目前我有这样的东西:
KERNEL=$(uname -r)
declare -i MINOR_VERSION=$(echo $KERNEL | cut -c 3-4)
if [ "10" -gt "$MINOR_VERSION"]; then exit 0; fi
这是错误的代码,如果次要版本 < 10 则不起作用,因为我正在使用 cut 并且取决于它是两位数。我可能需要的是使用点来解析次要版本的东西。 示例:
$ uname -r
3.4.0-60-generic
$ MNR_VAR=<awesome bash code, with cut or sed or something>
$ echo $MNR_VAR
4
我一直在阅读 cut
和 sed
文档,但只是阅读起来很慢。我将不胜感激!
TL;DR - 寻找 bash 命令,该命令将提取变量中前两个点包围的 int
。 "3.13.0.x" returns '13', "3.2.0.x" returns '2' 等
编辑: 对于那些好奇的人,下面是一些答案。
uname -r | cut -d '.' -f2
uname -r | awk -F . '{print }'
kernel="$(uname -r)" | tmp="${kernel#*.}" | minor="${tmp%%.*}" | echo "$minor"
问题是您正在使用 -c
到 cut
。不要那样做。
使用 -f
和 -d
标志来控制要输出的分隔符和字段。
或使用awk -F . '{print }' <<< "$(uname -r)"
.
或使用 IFS=. read -r _ minor _rest <<< "$(uname -r)"; echo "$minor"
(其优点是不使用任何外部实用程序)。
<<< "$(uname -r)"
的用法是 bash 特定的(我相信)但避免了对管道 (|
) 和它的子 shell 的需要涉及。
纯bash:
#!/bin/bash
ker="$(uname -r)"
minker="${ker#*.}"
minker="${minker%%.*}"
echo "$minker"
"${ker#*.}"
是$ker
中第一个.
匹配之后的字符串。因此
$minker
从 3.13.0-generic...
13.0-generic...
"${minker%%.*}"
是 $minker
中 .
及其后的所有匹配项(从右开始)剪切后留下的字符串。因此 $minker
从 13.0-generic...
13
See the Bash Parameter Expansion Manual for more info
使用 Bash 正则表达式:
#!/bin/bash
regex='([0-9]+)\.([0-9]+)'
[[ $(uname -r) =~ $regex ]]
echo ${BASH_REMATCH[2]}
仅提取次要版本并将其与某些内容进行比较是有风险的,因为主要版本号也可能发生变化...
我通常更喜欢用零填充数字,这样可以使用简单的字符串比较轻松地比较它们。
kernel_version=$(uname -r | sed -r 's/([0-9]+)/0000/g; s/0*([0-9]{4})//g') # gives 0003.0004.0000-0060-generic
if [[ "$kernel_version" < "0003.0010" ]]; then exit 0; fi