0

I am very new to shell scripting and using CLI all together. However, I want to create a simple program that can collect arguments from a user.

Optimally, I want my shell script to get a network name and instance name from the user, and assign the values to variables.

I know that $# can be used to gather arguments, but are there any other ways? I often notice when I make a command, there is, for example, something like this: $create --instance_name NAME . Can I gather an argument by using -- to specify the parameter? If so, here is an example of the command:

$collect_variable.sh --network NETWORK_NAME --instance_name INSTANCE_ID

Once again, thank you for any help. I am very new to stack overflow and unix all together, and any help is appreciated.

Lucas Whitaker
  • 99
  • 1
  • 1
  • 6

2 Answers2

0

You can using a variable to assign to for example:

 while getopts "x:y:z:" res
  do
   case "$res" in
     x ) paramX="$OPTARG" ;;
     y ) paramY="$OPTARG" ;;
     z ) paramX="$OPTARG" ;;
     ? ) echo "not a valid value"
   esac
  done

Check the rest of the links that other StackO users sent, they provide great examples! Hope that can help you solve your issue. Peace!

JorgeHPM
  • 125
  • 8
0

There are lots of ways of gathering arguments. You can name their position, e.g. $1 is the first argument and $14 is the fourteenth.

You can refer to the argument list like $@ (this preserves spacing) or like $* (this collapses spacing):

test_args() {
  echo '# as "$@"'
  for argument in "$@"; do
    echo "$argument"
  done

  echo '# as "$*"'
  for argument in "$*"; do
    echo "$argument"
  done

  echo '# as $*'
  for argument in $*; do
    echo "$argument"
  done
}
$ test_args "1 2" three four
# as "$@"
1 2
three
four
# as "$*"
1 2 three four
# as $*
1
2
three
four

Since you're exclusively using long options separated from their arguments by spaces,

while [ "$#" -gt 0 ]; do
  case "$1" in
    ( --network )           NETWORK="$2"; shift ;;
    ( --network=?* )        NETWORK="${1#*=}" ;;
    ( --instance_name )     INSTANCE_NAME="$2"; shift ;;
    ( --instance_name=?* )  INSTANCE_NAME="${1#*=}" ;;
    ( -* )                  echo "Illegal option -- $1" >&2; exit 2 ;;
    ( * )                   break ;;  # perhaps non-options are used later
  esac
  shift
done

This loops on each option and parses it. There are two conditions for each option, which lets us handle when the arguments are spaced from the options (--network bobnet) or when they're assigned to the options (--network=bobnet). Spaced means we need to refer to the next argument (thus the extra shift) while assigned means we need to use parameter subsitution to remove the characters at the front of the string up until (and including) the first =.

The final shift pulls the first item off of the argument list so we can operate on the next one. Shifting separately for the two-argument clauses (rather than ending with shift 2) also allows for binary options like --verbose, which doesn't contain an argument.

You can also use a while getopts loop to support a mix of short and long arguments; see my more detailed post on getopts.

Adam Katz
  • 14,455
  • 5
  • 68
  • 83