如何在Bash中简单计算两个变量的最小值?

62

我有一个Bash脚本,用于检查平台上的CPU数量,以便有效地使用-j选项进行make、repo等操作。我使用以下命令:

JOBS=$(cat /proc/cpuinfo | grep processor | tail -1 | sed "s,^.*:.*\([0-9].*\)$,\1,")
echo -e "4\n$JOBS" | sort -r | tail -1

它工作得很好。但是,我想知道是否有任何内置函数可以执行相同的操作(即计算最小值或最大值)?


2
与您的问题无关,但是您的“cat”管道应该做什么?似乎“grep ^processor /proc/cpuinfo | sed -n -e '$s/.*://p'”也同样有效。 - sorpigal
关于您的“有多少个内核”管道的另一个注意事项:由于您想知道系统中有多少个内核可用,因此您不必确定“最高处理器编号”,而实际上更安全和更简单的方法是,嗯,计算它们:grep ^processor /proc/cpuinfo | wc -l - creinig
仅使用 nproc 怎么样? - fwyzard
2个回答

143

如果您的意思是获取 MAX(4,$JOBS),请使用以下代码:

echo $((JOBS>4 ? JOBS : 4))

4
我理解您的意思是“我本意是指最小值,但是谢谢您的回答!” echo $(($JOBS<4?$JOBS:4))的翻译是:“输出变量$JOBS和数字4中的较小值。” - m-ric
23
谢谢,我不知道 $(( )) 支持三元运算符。非常有用。如果需要的话,你可以省略其中的 $ 符号:$((JOBS > 4 ? JOBS : 4)) - Tobia
@匿名 Bash没有本地支持浮点数,因此您必须使用非便携式解决方案,如bc,或进行一些聪明的黑客攻击,例如分离整数/小数部分并分别比较它们。 - Camilo Martin
我认为这个解决方案是 Bash 本地化的。进一步解释其工作原理,或者壳扩展的含义(或其他任何内容)将非常好。 - Sopalajo de Arrierez
这是一个非常简单的例子,通常被称为“三元运算符”,存在于许多编程语言中,只需在谷歌上搜索即可。 - mvds

34

我曾遇到过类似的情况,需要从多个变量中找到最小值。我发现一个有用的不同解决方案是使用sort函数。

#!/bin/bash

min_number() {
    printf "%s\n" "$@" | sort -g | head -n1
}

v1=3
v2=2
v3=5
v4=1

min="$(min_number $v1 $v2 $v3 $v4)"

我猜这不是最有效的技巧,但对于少量的常量变量来说,它不应该有太大影响,而且比嵌套三元运算符更易读。


编辑: 参考Nick的评论 - 这种方法可以扩展到任何类型的排序使用中:

#!/bin/bash

min() {
    printf "%s\n" "${@:2}" | sort "$1" | head -n1
}
max() {
    # using sort's -r (reverse) option - using tail instead of head is also possible
    min ${1}r ${@:2}
}

min -g 3 2 5 1
max -g 1.5 5.2 2.5 1.2 5.7
min -h 25M 13G 99K 1098M
max -d "Lorem" "ipsum" "dolor" "sit" "amet"
min -M "OCT" "APR" "SEP" "FEB" "JUL"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接