-3

I want to convert following bash code in pure shell script (sh) language so that it should run by other script language mode i.e dash script.

arguments=("$@")
for (( i=0; i<$#; i++ )); do
  case "${arguments[$i]}" in
    -foo)
    let "i = i + 1"
    echo "${arguments[$i]}"
      ;;
    *)                                                                                        
      break
  esac
done 

above code finely run in bash mode but through an error on dash mode.

2: ./orig.sh: Syntax error: "(" unexpected

Now If I change line 2 to get rid the error as following line

arguments="$@"

But now I got another error about loop

 3: ./orig.sh: Syntax error: Bad for loop variable
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Equation Solver
  • 545
  • 7
  • 18

3 Answers3

4

POSIX sh doesn't support arrays or C-style for loops.

i=0
while [ $(( ( i += 1 ) <= 10 )) -ne 0 ]; do
  eval "val=\$$i"
  case "$val" in
    -foo)
      i=$(( i + 1 ))
      eval "val=\$$i"
      echo "$val"
      ;;
    *)                                                                                        
      break
  esac
done 
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
3

The POSIX way to handle the arguments is to consume them using shift while $# is non-zero.

while [ $# -gt 0 ]; do
    case $1 in
      -foo)
        echo "$2"
        shift; shift
        ;;
      *)
        break ;;
    esac
done
chepner
  • 497,756
  • 71
  • 530
  • 681
-2

Now I have a Answer of my question, something like following works for me.

arguments="$@"
for i in $@; do
  case "$1" in
    -foo)
    shift 2
    echo "$1"
      ;;
    *)                                                                                        
      break
  esac
done
Equation Solver
  • 545
  • 7
  • 18
  • Don't ever do `arguments="$@"` in a POSIX shell -- it won't behave the way you expect. Compare the way it works when your script is run with `-foo "hello world"` and the way it works when your script is called with `-foo hello world`; the original bash script handled the former case, in particular, correctly. – Charles Duffy Oct 23 '14 at 16:25
  • also, using `$@` unquoted -- as you do here -- makes it behave the same way as unquoted `$*`, with all the pitfalls and caveats of that usage (stemming, principally, from string-splitting and glob expansion). Moreover, you don't even _need_ a for loop at all -- `while [ $# -gt 0 ]` would be more correct! – Charles Duffy Oct 23 '14 at 16:26
  • A good test, by the way, would be to see whether `./yourscript -foo "hello * world"` prints `hello * world` as it should -- that would catch both string splitting and glob expansion behavior. – Charles Duffy Oct 23 '14 at 16:29
  • This will also fail if you forget the second argument; `shift 2` will do nothing if there aren't two arguments to shift. – chepner Oct 23 '14 at 21:23
  • @CharlesDuffy, Hi, then what is the POSIX shell way to write the expression `arguments="$@"` – Equation Solver Oct 27 '14 at 12:42
  • @EquationSolver, there *is* no POSIX shell way to write that expression, since POSIX has no way to store an array (a list of separate arguments) in a single variable while preserving the original delimiters. – Charles Duffy Oct 27 '14 at 14:31
  • ...this shouldn't be surprising -- if POSIX sh were as expressive as bash, there would have been no need for bash to have created extensions in the first place. – Charles Duffy Oct 27 '14 at 23:26