30

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?

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

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.

  • 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 '16 at 15:24
  • That's not necessarily, but there must be coordination between #!/bin/sh and sh script.sh (or #!/bin/bash and bash script.sh) – Konstantin Morenko Jan 7 '16 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). – Stéphane Chazelas Jan 7 '16 at 15:38
  • 1
    I can die in piece from now on! :) – Paulo Mar 21 '17 at 18:41
0

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.

  • 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 – Eric Renouf Jan 7 '16 at 15:26
  • That was the part in which I was not entirely sure at the moment. Thanks for the clarification! – dave_alcarin Jan 8 '16 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).

  • Even if sh is a symlink to bash it will behave differently when invoked as sh – Eric Renouf Jan 7 '16 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.