1

I am trying to store a condition for comparing values in a variable but it is not working. The code I have written is :

read op
if [ $op == "desc" ]
then
compare='${arr[0]} -gt ${arr[1]}'
if [ eval "$compare" ]
then
 echo "SWAP"
 fi
fi

what am I doing wrong?

codeforester
  • 39,467
  • 16
  • 112
  • 140
  • BTW, the POSIX-standard string comparison operator is `=`, not `==`; see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html – Charles Duffy Mar 01 '18 at 00:17

2 Answers2

2

The right way to write your eval statement is:

if eval [ "$compare" ]
then
   ...

Don't use variables to store a command - see BashFAQ/050. You can rewrite your code as:

read op
if [ "$op" = "desc" ]; then
  if [ "${arr[0]}" -gt "${arr[1]}" ]; then
    echo "SWAP"
  fi
fi

Notes:

  • it's important to quote your variables inside [ ] to prevent word splitting and globbing
  • use shellcheck to validate your code

See also:

codeforester
  • 39,467
  • 16
  • 112
  • 140
  • depending on the user input the condition will change . so I was thinking if storing it in a variable rather than writing the loop multiple times. – Devendra Rawat Feb 28 '18 at 06:01
  • Use a `case` statement in such a situation, with explicit `if` statements and without any indirection or `eval`. That would be more readable and less error prone. – codeforester Feb 28 '18 at 06:03
  • 1
    @DevendraRawat, ...do read the link to BashFAQ #50 -- if you have code you want to avoid repeating, keeping that code in a function is generally the right choice. `mycompare() { [ "${arr[0]}" -gt "${arr[1]}" ]; }` will define the function, which can thereafter be used as `if mycompare; then`. – Charles Duffy Feb 28 '18 at 22:49
0

Given what the code does, eval isn't needed and this would be enough:

read op ; [ "$op" = "desc" ] && [ "${arr[0]}" -gt "${arr[1]}" ] && echo "SWAP"

(The above is functionally equivalent to codeforester's code.)

agc
  • 7,973
  • 2
  • 29
  • 50