111

I've been working on a script that automates setting up a development environment for Raspberry Pi development (step by step details that work are here). The script is linked in that article but convenience you can find it here also. Now when run this script install and sets up the environment without error but you have to enter your sudo password more than once due to sudo's time-out value by default. So I started experimenting by removing all the sudo lines and running the whole script via sudo at the command line like so:

kemra102@ubuntuvm:~$ sudo ./pi_dev_env_install.sh

This works fine as expected and gets most of the way through until this point:

./pi_dev_env_install: 68: ./pi_dev_env_install.sh: Syntax error: "(" unexpected

Now this line worked fine previously when not running the whole script with sudo. There is nothing about this line running as sudo that should stop it working to my knowledge, does anyone have any ideas?

kemra102
  • 1,111
  • 2
    The shebang is really in line 9? Due to Ubuntu's DashAsBinSh affinity I suspect your script is interpreted by dash instead of bash. Try to move the shebang in line 1. – manatwork Aug 18 '12 at 11:45
  • According to that article calling /bin/bash directly instead of /bin/sh will; correctly use bash instead of dash so that should not be an issue as I understand it. I can still move the shebang of course, but that doesn't really explain as to why it works when you don’t sudo the whole script. – kemra102 Aug 18 '12 at 11:50
  • 1
    In my case everything was fine but as a habit, I was running my shell script with "sh" not with "bash". – Indrajeet Gour Oct 11 '18 at 08:53

7 Answers7

145

The script does not begin with a shebang line, so the system executes it with /bin/sh. On Ubuntu, /bin/sh is dash, a shell designed for fast startup and execution with only standard features. When dash reaches line 68, it sees a syntax error: that parenthesis doesn't mean anything to it in context.

Since dash (like all other shells) is an interpreter, it won't complain until the execution reaches the problematic line. So even if the script successfully started at some point in your testing, it would have aborted once line 68 was reached.

The shebang line must be the very first thing in the file. Since you use bash features, the first line of the file must be #!/bin/bash or #!/usr/bin/env bash.

  • 3
    Thanks clearly a gap in my knowledge, I don't script much so wasn't aware of that! Thanks for the explanation it's helped a lot and will be very useful to know in the future too. – kemra102 Aug 18 '12 at 12:25
  • Let me add that this error occurs even while using scripts extension for nautilus. Adding the shebang line solved it immediately. +1. – Bhavin Doshi Oct 09 '13 at 05:14
  • Facing the issue running sonarqube.sh on Ubuntu 15.10. Changed the header as said. Executing sudo sh ./sonar.sh console. Still getting the error. – soufrk Sep 01 '16 at 06:58
  • @soufrk Is it sonarqube.sh or sonar.sh? Make up your mind. And anyway, if you can't solve the problem with the information in this thread, ask a new question with the full content of the script and copy-paste the full error message(s). – Gilles 'SO- stop being evil' Sep 01 '16 at 07:06
  • My bad !! Was running wrong arch executable. But interestingly, on the correct arch the file beginning with #! /bin/sh executed perfectly. Now, that leaves me puzzled. – soufrk Sep 01 '16 at 07:07
  • Another gotcha is if you do use the shebang, but your script is called from another script like so: sh ./pi_dev_env_install.sh. In this scenario, your shebang is ignored. To fix simply, remove the sh prefix and make sure the script has execute permissions, and you should be right. – alexkb Aug 20 '18 at 06:34
  • In my case a variable substituted in a command start-stop-daemon -e log_format=$log_format should have been enclosed in ' or ". Log format like %(asctime)s %(message)s not enclosed in ' disrupts parsing of the command. Proper command text should be start-stop-daemon -e log_format="$log_format". – yozniak Mar 26 '20 at 19:54
14

For me starting script with:

bash ./< script file > 

works fine.

jesse_b
  • 37,005
9

If the shebang is not on the first line, it will not be respected, regardless of the shell of the root user, the SHELL variable or the -s flag. You can easily confirm this is with a simple example:

#
#!/bin/bash
offset=(`ls`)
echo $offset

Running this script with sudo will raise a syntax error in recent versions of Ubuntu and Debian.

You have two options to make sure the script is interpreted by bash:

  1. Move the shebang to the first line

  2. Run sudo like this:

     sudo bash ./pi_dev_env_install.sh
    
Stephen Kitt
  • 434,908
janos
  • 11,341
1

This can happen if you override the intended interpreter. E.g this will run with sh regardless of what hash bang is used (handy when not using hash bang):

> sh run.sh

OR to run bash:

> bash run.sh

To let it use the script defined hash bang value, use this:

> ./run.sh
0

Try dos2unix in script file. Sometimes some hidden characters are there in the source.

command:

dos2unix script_file.sh script_file.sh
muru
  • 72,889
-1
sudo chmod 755 <script>

In my case the error was lack of permissions to execute the file. Only got the error message when I separated the commands:

$ sudo sh
# ./install
Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
-1

Maybe you have a "(" on the dir or file name.

mauro
  • 9