Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

[: -gt: unary operator expected

Tags:

bash

I don't write a lot of Bash, so I'm a bit stumped as to how to fix this. I need to check whether a value returned from a command is greater than x. When it runs though I get [: -gt: unary operator expected which I'm unable to fix.

Here is my script,

#!/bin/sh
ERROR=0
PHPCPDLevel=100

# PHPCPD
echo "PHP CopyPaste Detection (Limit is at least ${PHPCPDLevel}%"
PHPCPD="phpcpd ."
if [[ `echo $PHPCPD | grep "%" | cut -d'.' -f1` -gt "$PHPCPDLevel" ]]
  then
    echo $PHPCPD
    ERROR=1
  else
    echo "... -> Only `echo $PHPCPD | grep "%" | cut -d'.' -f1`%"
fi

echo "Finished!"
exit $ERROR

Update: I think I've done it:

#!/bin/sh
ERROR=0
PHPCPDLevel=25

# PHPCPD
echo "PHP CopyPaste Detection (Limit is at most ${PHPCPDLevel}%)"
PHPCPD="phpcpd ."
PERCENTAGE=$($PHPCPD | grep "%" | cut -d'.' -f1)
if [ ${PERCENTAGE} -gt ${PHPCPDLevel} ]
  then
    echo $PHPCPD
    ERROR=1
  else
    echo "Only $PERCENTAGE%"
fi

exit $ERROR
like image 559
James Avatar asked Jan 30 '26 06:01

James


1 Answers

Remember that [ is a command. It maybe built into your shell, but it's still a command. It is expecting a particular set of parameters, and will give you an error when it gets something it doesn't understand. In fact, you can replace [ ... ] with test ... if that makes things a bit easier to understand:

For example:

test -gt 34

Will return:

bash: test: -gt: unary operator expected

Hmmm... same error message.

When you get things like this, you should use set -xv and set +xv around the problem area of your shell script. The set -xv will print out the shell command to be executed, and then will show you what the command line looked like after it has been mangled I mean interpolated by the shell.

I suspect that your error is:

if [ ${PERCENTAGE} -gt ${PHPCPDLevel} ]

That ${PERCENTAGE} is a blank value. If you use [[ ... ]] instead of [ ... ] you won't get that error. The [[ ... ]] is parsed a bit differently than [ ... ] because it's a compound command. The shell interpolations are done after the initial command is parsed, so it's a bit more forgiving if you miss a quotation mark or strings contain unexpected characters.

So:

ERROR=0
PHPCPDLevel=25

# PHPCPD
echo "PHP CopyPaste Detection (Limit is at most ${PHPCPDLevel}%)"
export PS4="\$LINENO: "     # Prints out the line number being executed by debug
set -xv                     # Turn on debugging
PHPCPD="phpcpd ."
PERCENTAGE=$($PHPCPD | grep "%" | cut -d'.' -f1)
if [[ ${PERCENTAGE} -gt ${PHPCPDLevel} ]]  # Use [[ ... ]] instead of [ .. ]
then
    echo $PHPCPD
    ERROR=1
else
    echo "Only $PERCENTAGE%"
fi
set +xv                     # Turn off debugging

exit $ERROR

Now, you'll see what the various commands that set environment variables are returning, and possibly see something you didn't quite expect.

like image 128
David W. Avatar answered Jan 31 '26 21:01

David W.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!