-1

I'm working on a simple script that accepts multiple command line arguemnts in an order:

#!/bin/bash

function arg_parser () {
while [[ $# != 0 ]] ; do
  case "$1" in
    --one)
      varone="$2"
      ;;
    --two)
      vartwo="$2"
      ;;
    --three)
      varthree="$2"
      ;;
    --four)
      varfour="$2"
      ;;
    --five)
      varfive="$2"
      ;;
  esac
  shift
done
}

arg_parser "$@"

echo $varone
echo $vartwo
echo $varthree
echo $varfour
echo $varfive

Then run it:

./test.sh --one testone --three testthree --two testtwo --five "test five" --four "$$$$"
testone
testtwo
testthree
793793
test five

Notice how --four returns "793793" and not "$$$$"? Does anyone know why this is happening and/or how the script can be improved to prevent this from happening?

jasonwryan
  • 73,126

1 Answers1

0

$$ is a special variable that expands to the process id of the shell, in this case on the command line before your script even starts. Try something like echo $$. You'll need to escape the dollar signs with backslashes or put them in single quotes to not have them expand, i.e. echo '$$$$'.

The double quotes don't help, they'll just prevent word splitting of the expanded value, just like with regular variables ($foo vs. "$foo").

Also, in your loop, you shift only once even in the cases where you use the second argument too. This means that the arguments to your options are also processed as options themselves:

$ ./test.sh --one --two --three --four --five xyz
--two
--three
--four
--five
xyz

If you don't want that, you'll need to shift an additional time after using $2:

while [[ "$#" != 0 ]] ; do
  case "$1" in
    --one)
      varone="$2"
      shift
      ;;
    --two)
      vartwo="$2"
      shift
      ;;
    # ...
  esac
  shift
done
ilkkachu
  • 138,973