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?

choroba
  • 47,233
Lucy
  • 1

4 Answers4

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
Paul_Pedant
  • 8,679
  • 1
    and string sorting order comparisons also don't work, for pretty much similar reasons. – ilkkachu Feb 13 '22 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. – Paul_Pedant Feb 13 '22 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 '22 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
choroba
  • 47,233
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.

fuzzydrawrings
  • 1,656
  • 5
  • 12
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.

ilkkachu
  • 138,973