1

This snippet of code has been taken from a larger script, (humbly) simulating the non-existing abs() function:

[[ $(echo "$val < 0" | bc) -eq 1 ]] && val=$(echo "$val * -1" | bc)

So we test the number whether it is negative; if yes the second statement after the && will be executed. This was my original line.

Some other SE user later changed this into:

(( $(bc <<<"$val < 0") == 1 )) && val=$(bc <<<"$val * -1")

OK, though both of these apparently work, I still prefer mine as it does not only make use of the -eq operator (which has been implemented especially for non-strings) but it also avoids here-strings, which makes the code work better on read-only environments. (Keep in mind that /tmp MUST be writeable for here-strings to work.)

Lastly, I seem to remember that bc in the later line will output a true integer, which makes the use of == rather questionable, since this is only recommended to be used for strings. Unfortunately bc does not reveal in its man page either whether it outputs its results as plain numbers or strings.

Opinions?

  • 1
    If the number is always integer, why don't you just abs=${val#-}? – choroba Apr 17 '15 at 15:33
  • Just never thought of that, thanks for the inspiration. :) I'm a bash old-schooler and still not too familiar with the "modern" ${...#...} syntax using brace substitution. – syntaxerror Apr 17 '15 at 15:34
  • 2
    @syntaxerror; note that (not all but) this sort of variable expansion is even defined in POSIX. – Janis Apr 17 '15 at 15:42
  • 1
    It may be noteworthy that ksh supports abs(x) in arithmetic contexts. – Janis Apr 17 '15 at 15:51
2

You have confused here.

Both [[ $(echo "$val < 0" | bc) -eq 1 ]] and (( $(bc <<<"$val < 0") == 1 )) used integer comparison.

((..)) is equivalent to let builtin in ksh, bash and zsh. It evaluated arithmetic expression. Inside ((..)), all operators and their precedence, associativity, and values are the same as in the C language.

The one make you confuse was == inside new test operator [[...]]. When == available, it's equivalent with = and perform pattern matching. You need to double quotes either sides for doing string comparison [[ "$a" == "$b" ]].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.