Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to calculate the minimum of two variables simply in bash?

I have a bash script checking the number of CPUs on the platform to efficiently use -j option for make, repo, etc. I use this:

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

It works fine. But, I am wondering if there was any built-in function which does the same thing (i.e. calculating the minimum, or maximum)?

like image 443
m-ric Avatar asked May 02 '12 13:05

m-ric


People also ask

What does [- Z $1 mean in bash?

$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script.

What does $() mean in bash?

The dollar sign before the thing in parenthesis usually refers to a variable. This means that this command is either passing an argument to that variable from a bash script or is getting the value of that variable for something.

What does += mean in bash?

The += and -= Operators These operators are used to increment/decrement the value of the left operand with the value specified after the operator. ((i+=1)) let "i+=1"


2 Answers

If you mean to get MAX(4,$JOBS), use this:

echo $((JOBS>4 ? JOBS : 4))
like image 119
mvds Avatar answered Oct 18 '22 00:10

mvds


Had a similar situation where I had to find the minimum out of several variables, and a somewhat different solution I found useful was 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)"

I guess It's not the most efficient trick, but for a small constant number of variables, it shouldn't matter much - and it's more readable than nesting ternary operators.


EDIT: Referring Nick's great comment - this method can be expanded to any type of sort usage:

#!/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"
like image 33
Arnon Zilca Avatar answered Oct 17 '22 23:10

Arnon Zilca