title: Bash - how to avoid command "eval set --" evaluating variables
body: <p>I just write a little bash script for managing multiple parallels ssh commands.
  In order to parse arguments I use this piece of code : </p>
  
  <pre><code>#!/bin/bash
  
  # replace long arguments
  for arg in "$@"; do
      case "$arg" in
          --help)           args="${args}-h ";;
          --host|-hS)       args="${args}-s ";;
          --cmd)            args="${args}-c ";;
          *) [[ "${arg:0:1}" == "-" ]] &amp;&amp; delim='' || delim="\""
             args="${args}${delim}${arg}${delim} ";;
      esac
  done
  
  echo "args before eval : $args"
  eval set -- $args
  echo "args after eval  : $args"
  
  while getopts "hs:c:" OPTION; do
      echo "optarg : $OPTARG"
      case $OPTION in
      h)  usage; exit 0;;
      s)  servers_array+=("$OPTARG");;
      c)  cmd="$OPTARG";;
      esac
  done
  </code></pre>
  
  <p>So I can use for instance -s, --host or -hS for the same result.
  Everything works fine except one thing.</p>
  
  <p>If I put a variable in argument it will be evaluated.</p>
  
  <h3>Explanations</h3>
  
  <pre><code>./test.sh -s SERVER -c 'echo $HOSTNAME'
  </code></pre>
  
  <ol>
  <li><p><code>cmd</code> should be assigned to <code>echo $HOSTNAME</code> but because of the <code>eval set</code> cmd is in fact assigned to <code>echo server1</code> (the value of the variable)</p></li>
  <li><p>If I comment the line <code>eval set -- $args</code> I cannot use long options (--cmd) but <code>cmd</code> is assigned to <code>echo $HOSTNAME</code> as expected</p></li>
  </ol>
  
  <p>Is there any solution to avoid eval set / getopts to evaluate variables ?
  So to to have the same behavior as 2. but with long options available.</p>
  
  <h3>Examples</h3>
  
  <p>with eval set</p>
  
  <pre><code>./test.sh -s SERVER -c 'echo $HOSTNAME'
  args before eval : -s "SERVER" -c "echo $HOSTNAME"
  args after eval  : -s "SERVER" -c "echo $HOSTNAME"
  optarg : SERVER
  optarg : echo server1
  </code></pre>
  
  <p>without eval set (line <code>eval set -- $args</code> commented)</p>
  
  <pre><code>./test.sh -s SERVER -c 'echo $HOSTNAME'
  args before eval : -s "SERVER" -c "echo $HOSTNAME"
  args after eval  : -s "SERVER" -c "echo $HOSTNAME"
  optarg : SERVER
  optarg : echo $HOSTNAME
  </code></pre>