Ubuntu – bash script: different results when called with or without sudo

bashscriptssudo

In Ubuntu 16.04.3, I have a very simple bash script:

test.sh

[[ 0 == 0 ]] && result="true" || result="false"
echo $result
echo $USER $SHELL $0

When I call it as the non-root user me or as root, it works as expected. If I use sudo ./test.sh, it complains about a syntax error:

$ ./test.sh
true
me /bin/bash ./test.sh

$ sudo su
# ./test.sh 
true
root /bin/bash ./test.sh

# exit
$ sudo ./test.sh
./test.sh: 1: ./test.sh: [[: not found
false
root /bin/bash ./test.sh

What could be causing this? How can I fix it so that me can use this script both normally and with sudo?

Best Answer

Every script begins with a Shebang, without it the shell starting your script doesn't know which interpreter should run your script1 and might – as in the case of sudo ./script.sh here – run it with sh, which in Ubuntu 16.04 is linked to dash. The conditional expression [[ is a bash compound command, so dash doesn't know how to handle it and throws the error you encountered.

The solution here is to add

#!/bin/bash

as the first line of your script. You may get the same result when you call it explicitly with sudo bash ./script.sh, but a shebang is the way to go.
To check which shell runs your script, add echo $0 to it. That's not the same as echo $SHELL, citing wiki.archlinux.org:

SHELL contains the path to the user's preferred shell. Note that this is not necessarily the shell that is currently running, although Bash sets this variable on startup.

1: As you started ./test.sh with bash it just assumed bash, the same goes for the sudo su subshell.