2

My if expression always evaluates to TRUE somehow. ROTATION variable is 0.000 or 90.000, a float value or it seems so

ROTATION="$(mediainfo --Inform="Video;%Rotation%" $VIDEO$ORIGINALEXTENTION)"
echo $ROTATION

ROTATION_PARAMETER=""

if [ $ROTATION -eq 90 ]
then
    ROTATION_PARAMETER=" --rotate=4"
fi

echo $ROTATION_PARAMETER

How can I compare a variable to a value?

1
  • 2
    bash can handle only integers.
    – jimmij
    Feb 6, 2015 at 15:56

5 Answers 5

3

You can use bc command for this puspose:

echo "$ROTATION == 90"|bc

and you will get 0 in case of false and 1 in case of true

P.S. Be aware that comparing for equivalence floating point numbers is not the wisest thing in programming :)

4
  • 2
    You can use: if [ $(echo "$ROTATION == 90" | bc) -eq 1 ]
    – jofel
    Feb 6, 2015 at 16:04
  • @jofel, the good practice is to make it on this way: if [ "$(echo "$ROTATION == 90" | bc)" -eq 1 ] :) Feb 6, 2015 at 16:05
  • 2
    Since this is bash: if (( $(bc <<< "$ROTATION == 90") == 1 )) Feb 6, 2015 at 16:21
  • 1
    @glennjackman, thank you for the idea. I personally prefer to use old sh syntax :) But you should use -eq 1 because == in bash is to compare strings Feb 6, 2015 at 16:24
1

Because they are strings, you can compare multiple concatenated strings against one another. Balancing values makes for simple means of handling multiple shell tests at once.

[ "${num#90.}${num%[!0]*}" = "90${num%[!0]*}" ] && do_it

But that only works if $num is definitely a number. You can validate an integer value for $num like:

[ "$num" -eq "$num" ]

Or a float like:

[ "${#num}${num#*.}" -ne "${num%.*}${#num}" ]

But case is usually best...

case ".${num##*[!-.0-9]*}" in
(.|.[!9]*|.9[!0]*|.90.*[!0]*) 
! :;;esac 

Where outside utilities are concerned, I usually prefer dc to bc because it can be used to execute arbitrary system commands:

dc -e '[!echo execute arbitrary system command]s=' \
   -e '90 90.0 =='

Everything within the [] brackets is a string that is saved to the array named = and which is executed as a dc command if the top two values on the main stack (here 90 and 90.0) = one another. The first ! operator within the string is ! operator which executes as a system command all that follows it. You can also read from input for more dc script to execute conditionally with the ? operator.

The -expression syntax is a GNUism, though. You can get the same effect portably with a heredoc or echoing the commands over a pipe to its stdin.

For example:

! dc -e '[!kill -PIPE "$PPID"]s= 90 90.0 ==' && do_it
2
  • 1
    You have to more think above. 90,001 == 90 in your script.
    – Costas
    Feb 6, 2015 at 16:27
  • @Costas - good point. Will fix.
    – mikeserv
    Feb 6, 2015 at 16:44
0

You can compare values just like a string:

{ printf "[ %.3f == %.3f ]\n" $ROTATION 90 | bash ; } && ROTATION_PARAMETER=" --rotate=4"

Or even

[ $(printf "%.3f == %.3f" $ROTATION 90) ] && ROTATION_PARAMETER=" --rotate=4"

Be attentive that some locales require , instead . as decimal separator so $ROTATION should be in 90,000 form.

0

Since you're already using zsh syntax instead of bash syntax (by not quoting your variables), just switch to zsh where you can do:

 if (( ROTATION == 90 )); then...

(that would work in ksh93 as well).

But if the value is always expressed as 90.000, then you can also do a strong comparison:

 if [ "$ROTATION" = 90.000 ]; then...
2
  • 1
    In your last comparation 90.00 != 90.000
    – Costas
    Feb 6, 2015 at 17:25
  • @Costas, no, but that 90.00 fails the if the value is always expressed as 90.000 assumption. Feb 6, 2015 at 17:35
0

Consider calling a scripting language which is a bit more prepared to deal with floating point values, something akin to:

ROTATION=...
if $( perl -e 'use POSIX "fmod";if(fmod($ENV{ROTATION}, 90.0)<0.001) {exit(0)} else{exit(1)}' )
then...

(might have those exit return codes backwards)

1
  • In bash you can't do directly math operations with floating point. So you should use bc, awk, perl, etc. Feb 6, 2015 at 16:38

You must log in to answer this question.

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