0
monterey2="12.0"
macOS=$(sw_vers -productVersion)
if [ "$macOS" >= "$monterey2" ] ; then
  echo "Monterey"
else 
  echo "not Monterey"
fi
exit 0

Ouputs this error -> "[: 12.2.1: unary operator expected".. I've tried -eq as well with same result. What am I doing wrong?

0

4 Answers 4

2

Echo the two version numbers into sort -V and see which number comes out first (as text). If it matches $monterey2 as text, then the one from sw_vers is greater or equal.

Float comparisons do not work on version numbers, because the individual parts are integers (and not necessarily only two of them). Examples:

12.3 is earlier than 12.10
12.3.11 is later that 12.3.8
3
  • 1
    and string sorting order comparisons also don't work, for pretty much similar reasons.
    – ilkkachu
    Feb 13, 2022 at 21:02
  • @ilkkachu I had forgotten how smart sort -V is. It will handle alpha in version numbers too, and allows -f to fold upper/lower in such cases. Feb 13, 2022 at 21:25
  • yeah I meant that simple string comparison like plain sort or [[ a < b ]] fail same as simple numeric comparisons. sort -V is another thing entirely, it even supports Debian's tilde-suffixes for pre-versions (1.2~rc1 < 1.2 < 1.2-foo). Well, at least the one on Debian does. ;)
    – ilkkachu
    Feb 13, 2022 at 22:36
0

Under [, only > is supported for string comparison, not >=. For numeric comparison, you can use -ge, but 12.2.1 is not an integer, so it's not valid for numeric operators.

If you want to check for Monterey only, use = (string equality):

if [ "$macOS" = "$monterey2" ] ; then
1
  • Thanks for your comment. I do want it to be "is greater than or equal to".
    – Lucy
    Feb 13, 2022 at 19:03
0

The problem is test can only understand integers or strings but you want to compare floating point numbers. I'd suggest using bc to get the comparison result.

In particular, change this:

if [ "$macOS" >= "$monterey2" ] ; then

To this:

if [ $(echo "$macOS >= $monterey2" | bc) ]; then

EDIT

This actually won't work in your situation where the version numbers have more than one decimal like 12.2.1.

0
    if [ "$macOS" >= "$monterey2" ] ; then

Ouputs this error -> "[: 12.2.1: unary operator expected".. What am I doing wrong?

This happens because [ is a normal command, and so > works in the usual way as the redirection operator. The word after that, =, is taken as the file name, and both are removed before they're passed to the [ command. So, if you have in effect e.g. [ 12.2.1 >= 12.0 ], it's similar to [ 12.2.1 12.0 ] > outputfile, just with an odder filename and more confusing ordering.

[ sees two arguments before the closing ], so it expects a unary operator and the operand to it. That would be stuff like e.g. [ -f xyz ] to check if xyz is an existing regular file. Of course, 12.2.1 isn't a valid operator, so you get the error. Also, you'll find that file called = in the directory you ran the script in.

I've tried -eq as well with same result.

Well, it's not the same result, since the error message is "integer expression expected", as you mentioned in the question title. Bash only does integer arithmetic, and your values aren't integers. There's workarounds in How to do integer & float calculations, in bash or other languages/frameworks?

However, as other answers mention, you can't compare version numbers as decimal / floating point numbers anyway. While 12.0 is a number, 12.2.1 isn't.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .