0

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.

codeforester
  • 39,467
  • 16
  • 112
  • 140
Panch
  • 1,097
  • 3
  • 12
  • 43

2 Answers2

3

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.

rici
  • 234,347
  • 28
  • 237
  • 341
  • It doesn't seem to be an issue with the shebang line. – codeforester Feb 13 '17 at 03:38
  • 1
    My script had `#!/bin/sh` at the top of the script hence I run in to the issue. Thanks for pointing out that "`sh` does not implement arrays". I changed the line `#!/bin/sh` to `#!/usr/bin/env bash` that works fine now. – Panch Feb 13 '17 at 03:41
  • 1
    @codeforester: Evidently on *your* system, `sh` is `bash`. Not everyone has their machine configured that way. – rici Feb 13 '17 at 03:44
  • @rici - you are right. But, I read somewhere that `bash` would behave differently when it is invoked as `sh`. I wonder why that's not happening in my case. – codeforester Feb 13 '17 at 03:45
  • @codeforester: "I read somewhere" is not a substitute for RTFM :) – rici Feb 13 '17 at 03:48
  • @rici - "somewhere" was here: http://stackoverflow.com/a/5725297/6862601 – codeforester Feb 13 '17 at 03:51
  • In particular, bash attempts to mimic a posix shell in situations *where the correct behaviour would be different*. For example, it follows a different startup sequence. However, bash extensions like arrays and the indirection operator work as normal. (But not process substitution. There is probably a reason for that.) – rici Feb 13 '17 at 03:51
  • @codeforester: Yes, the comment to that answer points to a list of differences in Posix mode, which is considerably more accurate than my rough summary above. But in any case, arrays aren't mentioned in that list. – rici Feb 13 '17 at 03:55
-1

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 
Hasan Alizada
  • 591
  • 4
  • 13