# Understanding `echo \$((0x63))`

I was searching for a way to convert hexadecimal via command line and found there is a very easy method `echo \$((0x63))`.

It's working great but I'm a little confused as to what is happening here.

I know `\$(...)` is normally a sub-shell, where the contents are evaluated before the outer command.

Is it still a sub-shell in this situation? I'm thinking not as that would mean the sub-shell is just evaluating `(0x63)` which isn't a command.

Can someone break down the command for me?

`\$(...)` is a command substitution (not just a subshell), but `\$((...))` is an arithmetic expansion.

When you use `\$((...))`, the `...` will be interpreted as an arithmetic expression. This means, amongst other things, that a hexadecimal string will be interpreted as a number and converted to decimal. The whole expression will then be replaced by the numeric value that the expression evaluates to.

Like parameter expansion and command substitution, `\$((...))` should be quoted as to not be affected by the shell's word splitting and filename globbing.

``````echo "\$(( 0x63 ))"
``````

As a side note, variables occurring in an arithmetic expression do not need their `\$`:

``````\$ x=030; y=30; z=0x30
\$ echo "\$(( x + y +x ))"
78
``````
• Also note that because `\$((...))` conflicts with command substitution, one has to remember to write `echo "\$( (echo x; echo y) | tr xy yx)"` instead of `echo "\$((echo x; echo y) | tr xy yx)"` (even though some shells will still accept the latter, YMMV). Commented Nov 1, 2017 at 14:52
• @StéphaneChazelas And how do you make `\$(( ))` produce output which is affected by word splitting or globbing? Commented Nov 1, 2017 at 15:25
• @HaukeLaging, `IFS=9; echo \$((0x63))`. See also Security implications of forgetting to quote a variable in bash/POSIX shells (`What about [ \$# -gt 1 ]` section) Commented Nov 1, 2017 at 15:28

This is not a subshell, but arithmetic evaluation. From `man bash`:

((expression))

The expression is evaluated according to the rules described below under ARITHMETIC EVALUATION. 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".

• `((...))` is not quite the same as `\$((...))`. Both does arithmetic evaluation, but the latter is replaced by the resulting value as a string. Commented Nov 1, 2017 at 14:43