Panch
Panch

Reputation: 1187

Bash: syntax error: "(" unexpected

The below is the snippet of my script which throws the error while running it:

echo "#include \"Factory.H\"" > $1
echo "#include \"Stub.H\"" >> $1
echo "#include \"Ref.H\"" >> $1

#
# a loop to include all of the headers for the stubs.
#
ARGS=("$@")
for ((i = 1; $i < $#; i=$i+2)) ; do 
    echo ${ARGS[$i]}
    echo "#include \"${ARGS[$i]}.H\"">> $1
done 

The error reported in the ARGS=("$@"), I could not figure out why this is being reported as an error. The script is invoked with the following input

..//scripts/makestubfactory ./obj/_stubfactory.C RegistryImpl_Stub "com.frco.fievel.comm.registry.RegistryImpl_stub" ObserverBrokerImpl_Stub "com.frco.fievel.observer.ObserverBrokerImpl_stub" SubjectAccessImpl_Stub "com.frco.fievel.observer.SubjectAccessImpl_stub"

Please shed some lights on how to sort out this issue.

Upvotes: 0

Views: 1468

Answers (2)

rici
rici

Reputation: 241721

You need to make sure that your script is run with the bash shell, since a standard Posix shell (which is what sh might be on your system) does not implement arrays. To do so, you should add a shebang line as the first line of your script:

#!/usr/bin/bash

The path /usr/bin/bash must be the full path to the bash executable, which might be in some other location on your machine. Some people prefer to use

#!/usr/bin/env bash

which will find bash wherever it is in the PATH, but requires env to be at the fixed location.

You can find the path to the bash executable from bash by using the command:

which bash

There are a number of improvements which could be made to this script, some of which I noted in a quick glance:

  1. You can use single quotes to avoid having to backslash escape the double quotes (but only if you don't have single quotes or variable expansions inside your strings). Variable expansions, on the other hand, should be quoted:

     echo '#include "Factory.H"' > "$1"
    
  2. Even better, use a here-doc to copy an entire template:

    cat >"$1" <<"EOF"
    #include "Factory.H"
    #include "Stub.H"
    #include "Ref.H"
    EOF
    
  3. You don't really need an array, since you can use bash's indirection operator to access command-line arguments:

    for ((i=2; i<$#; i+=2)); do
      echo "${!i}"
      echo "#include \"${!i}\".H" >> "$1"
    done
    

    Note the use of i+=2 rather than i=$i+2.

    Another solution, using printf to output all the arguments in one call:

    printf '#include "%s.H"\n%.0s' "${@:2}"
    

    This makes use of the fact that the shell printf utility keeps repeating the format until it has used up all the arguments, which can be very helpful. In this case, I use %.0s (i.e. print a string with maximum length 0) to not print the odd arguments. "${@:2}" is a bash extension which is like "$@" except that it starts with argument 2.

Upvotes: 3

Hasan Alizada
Hasan Alizada

Reputation: 591

Try this:

echo "#include \"Factory.H\"" > $1
echo "#include \"Stub.H\"" >> $1
echo "#include \"Ref.H\"" >> $1

#
# a loop to include all of the headers for the stubs.
#
ARGS=("$@")
for ((i = 1; $i < $@; i=$i+2)) ; do 
    echo ${ARGS[$i]}
    echo "#include \"${ARGS[$i]}.H\"">> $1
done 

Upvotes: -1

Related Questions