5 ms·
I was today years old when I learned that bash can do simple arithmetic with $(($i + 1)). Thanks!
by sillysaurusx 4y ago
I was today years old when I learned that bash can do simple arithmetic with $(($i + 1)). Thanks!
- mmh0000 4y agoIf you just want to add/subtract 1, in bash you can do just '((i++))', i.e.: [mmh@x670]$ i=0 [mmh@x670]$ ((i++)); echo $i 1 [mmh@x670]$ ((i++)); echo $i 2 Beware that the above is very -bashy- and purists will rip your head off for using it.
- sillysaurusx 4y agoWhoa. No dollar signs at all? I’m at Lowes — does ((i+1)) work? Or is it just for incrementing / decrementing (which is still very useful!) EDIT: thinking this over, does this work for variable substitution too? E.g. ((i)) being equivalent to $i. Not that you’d necessarily want to…
- mmh0000 4y agoTo add arbitrary numbers, you'd have to do an assignment, like this: [mmh@x670]$ ((i=i+2)); echo $i 6 [mmh@x670]$ ((i=i+2)); echo $i 8
- Arnavion 4y ago`(( ))` is an arithmetic evaluation block. Its content has to be an arithmetic expression. Arithmetic expressions don't require `$` before simple variable names and some more complex expressions like array indexing. `(( i + 1 ))` will evaluate the result of adding one to `$i` and then throw away the result. It doesn't do anything useful (other than having a different exit code depending on whether the expression evaluated to 0 or not). `$(( ... ))` evaluates the expression and then returns its value. ie `i=$(( i + 1 ))` will increment `$i`, just like `(( i++ ))` did.
- mmh0000 4y agoAlso, the wooledge wiki is an amazing resource for Bash/shell scripting. To learn more magic see: https://mywiki.wooledge.org/ArithmeticExpression https://mywiki.wooledge.org/ArithmeticExpression
- cmckn 4y agoThere is a gotcha here if you use: set -o errexit Because *any bash arithmetic expression that evaluates to zero returns the exit code of 1*. So this works: #!/usr/bin/env bash set -o errexit i=0 ((++i)) echo $i # 1 will be printed to stdout But this doesn't: #!/usr/bin/env bash set -o errexit i=0 ((i++)) # terminates here with $? of 1 echo $i The relevant doc is for `let`: let arg [arg ...] Each arg is an arithmetic expression to be evaluated (see ARITHMETIC EVALUATION above). If the last arg evaluates to 0, let returns 1; 0 is returned otherwise. https://www.gnu.org/software/bash/manual/bash.html#index-let https://www.gnu.org/software/bash/manual/bash.html#index-let
- chubot 4y agoYeah it's best to just use POSIX shell arithmetic, and not be clever, and not the other 2 ways bash has to do it! THat is: i=$((i + 1)) The (( )) construct, without the $, is different, and it's also not POSIX. It has the gotchas around the exit code, which a plain assignment doesn't have.
- fab23 4y agoIt does also matter where the plus signs are: $ i=0 $ echo $((++i)) 1 $ echo $((i++)) 1 $ echo $((++i)) 3 $ ((++i)) does add 1 before the command is run, and ((i++)) does add 1 after the command is run.
- jwilk 4y agoOr, more simply, $((i + 1)). And it's not only bash; it's feature of POSIX shell.
- jcynix 4y agoOr with two brackets instead of four parens: $[i+4] And, btw, res=$(command) instead of those pesky backticks res=`command` ,-)
- bdowling 4y agoYou can also use the builtin command `let`: let count=0 until "$@"; do let wait=2**count sleep $wait let count=count+1 done
- yx827ha 4y agoDon't forget about: declare -i i i+=1