55

I have two (Debian) Linux servers. I am creating a shell script.

On the first one I create an array thus:

#!/bin/bash
target_array=(
    "/home/user/direct/filename -p123 -r"
)

That works fine. But when I run this on the other server I get:

Syntax error: "(" unexpected

As far as I can tell both servers are the same. Can anyone shed some light on why this doesn't work?

If I type it into the terminal directly it is fine??


It would appear that when I run it as

sh scriptname.sh

I get the error, but if I run it as

./scriptname.sh

it seems to be ok. What's the difference?

2
  • Did you copy-pasted the script between the two server? try cat -v <script> to see if there are spurious char.
    – LilloX
    Jan 7, 2016 at 14:50
  • 2
    sh is not bash and so running it as sh scriptname.sh is wrong Jan 7, 2016 at 15:01

3 Answers 3

94

When you use ./scriptname.sh it executes with /bin/bash as in the first line with #!. But when you use sh scriptname.sh it executes sh, not bash.

The sh shell has no syntax to create arrays, but Bash has the syntax you used.

4
  • OK, that makes sense now. As you can probably tell I'm quite new to Linux (currently trying to convert my Powershell scripts shell/bash scripts). I will stick to using ./ from now on. cheers
    – IGGt
    Jan 7, 2016 at 15:24
  • 2
    That's not necessarily, but there must be coordination between #!/bin/sh and sh script.sh (or #!/bin/bash and bash script.sh) Jan 7, 2016 at 15:26
  • 3
    The sh language has no arrays (a[index]=x or a=(x y)). Some sh interpreters support arrays, only ksh88 (not ported to Linux AFAIK) and some older pdksh variants would support a[index]=value and not a=(x y). On Debian, sh is usually dash which has no array support (a[index]=x won't work). Jan 7, 2016 at 15:38
  • 1
    I can die in piece from now on! :)
    – Paulo
    Mar 21, 2017 at 18:41
1

Running ./scriptname.sh will result in reading the first line of the file and see that it needs to run ´/bin/bash´ and pass the rest of the script to the interpreter, while executing sh scriptname.sh will pass the file to the user's standard shell (e.g. Ash) and be the case that that other interpreter does not support arrays as Bash does.

2
  • 1
    sh is not necessarily the "user's standard shell" it's often its own executable (or symlink) and sh will be invoked to process the script. That will be true if even if the default login shell for that user is bash Jan 7, 2016 at 15:26
  • That was the part in which I was not entirely sure at the moment. Thanks for the clarification! Jan 8, 2016 at 8:44
0

With sh scriptname.sh, you are running it with sh, not necessarily with bash. Try comparing sh --version on both machines. And/or with dpkg -S $(which sh).

1
  • Even if sh is a symlink to bash it will behave differently when invoked as sh Jan 7, 2016 at 15:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.