3

Have following line in bash script, parsing input arguments:

((10#$2 > 0)) 2>/dev/null && shift 2 || shift

Basically it helps handling parameters with optional integer subparameter. Like:

-x 100 -y

-x -y

Could you explain how it works.

1
  • You can get the same result with much less fuss if you shift ${2+$(((10#$2>0)+1))}.
    – mikeserv
    Mar 21, 2014 at 19:06

1 Answer 1

6

The line checks whether the second positional parameter is greater than 0. If the condition is true then it shifts the positional parameters 3, 4, ... to 1, 2, ... If the condition is false then it shifts the positional parameters 2, 3, ... to 1, 2, ...

Constants with leading zero are interpreted as octal numbers. Saying 10#$2 causes the positional parameter $2 to be interpreted as a decimal. You might also want to refer to Shell Arithmetic.

As such, ((10#$2 > 0)) checks if the second positional parameter represented in base 10 is greater than 0. 2>/dev/null causes any errors resulting from this test to be redirected to /dev/null. See Bash Arithmetic Expressions for more on the # operator.

&& and || are conditional constructs. So if the condition is true then shift 2 is executed else shift is executed.

expression1 && expression2

True if both expression1 and expression2 are true.

expression1 || expression2

True if either expression1 or expression2 is true.

As an example, refer to the following:

$ ((10>42)) && echo greater || echo smaller    # Condition is false so the `echo smaller` expression is evaluated
smaller
$ ((100>42)) && echo greater || echo smaller   # Condition is true so the `echo greater` expression is evaluated
greater

Quoting from the manual:

((...))

(( expression ))

The arithmetic expression is evaluated according to the rules described below (see Shell Arithmetic). If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to

let "expression"
4
  • Perhaps an example would help illustrate this better, it's a little hard to follow and the OP appears new to all this. Explain what's going on with the 10#$2 since that's the most magical part.
    – slm
    Mar 21, 2014 at 13:34
  • @slm I was about to add parts. Sorry didn't add everything to begin with.
    – devnull
    Mar 21, 2014 at 13:48
  • NP - I do the same, sorry should've waited 8-)
    – slm
    Mar 21, 2014 at 13:51
  • As for the last - n > n && echo || echo , you can also use a ternary expression: t=20 ; f=10 ; s=1 ; b=2 ; echo $((tern=s<b?t:f)) ; echo $tern - 20\n20 unix.stackexchange.com/a/119314/52934
    – mikeserv
    Mar 21, 2014 at 20:51

You must log in to answer this question.

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