1

I want to make a script /bin/sh compatible. At some point I was using a print-out of a hex variable to its decimal value but it is throwing this error:

sh: 1: arithmetic expression: expecting EOF: "16#c0"

That error is not present when the script is executed by /bin/bash. I boiled it down to the following problem:

$ sh -c 'echo $((16#c0))'     
sh: 1: arithmetic expression: expecting EOF: "16#c0"

$ sh -c "echo $((16#c0))"    
192

Why is that and how can I get echo working in my script?

EDIT: subshell is redirected to /bin/dash

$ readlink -f $(which sh)
/bin/dash
$ type sh
sh is /bin/sh
user8162
  • 391
  • 3
  • 12

1 Answers1

4

sh (often simlink to a POSIX shell like dash) doesn't support arithmetic evaluation in the form [base#]n like bash is supporting.

So you need to use the 0x prefix with your hexadecimal number:

sh -c 'echo $((0xc0))'

or

sh -c 'printf "%d\n" 0xc0'

Note that you always need to use single quote to not let the current shell interpreting the content of the double quoted string.

So your attempt with

sh -c "echo $((16#c0))"

looks to be working only because the $((16#c0)) is interpreted by bash and the actual command executed by sh is echo 192.

oliv
  • 12,690
  • 25
  • 45
  • That was helpful. I never would have thought that the subshell could be something different than the "host" shell. Is there a way to to check this? – user8162 Oct 29 '18 at 07:32
  • @user8162 Try `type sh` or `readlink -f $(which sh)` to see if this is a symbolic link to something else. – oliv Oct 29 '18 at 07:35
  • Technically, there's no subshell; you are running the program `sh` from a `bash` shell, not starting a new shell in the same process. The double-quoted argument is simply evaluated by `bash` before `sh` is ever executed; your second attempt is equivalent to `sh -c "echo 192"`. – chepner Oct 29 '18 at 15:13