如何从命令行收集参数?

时间:2019-07-09 14:41:04

标签: linux shell unix cygwin command-line-interface

我对Shell脚本和同时使用CLI都是很陌生的。但是,我想创建一个可以从用户收集参数的简单程序。

理想情况下,我希望我的shell脚本从用户那里获取网络名称和实例名称,并将其值分配给变量。

我知道$#可用于收集参数,但是还有其他方法吗?我经常在执行命令时注意到,例如:$ create --instance_name NAME。我可以使用-指定参数来收集参数吗?如果是这样,下面是命令示例:

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

再次感谢您的帮助。对于堆栈溢出和UNIX在一起,我是一个新手,我们将为您提供帮助。

2 个答案:

答案 0 :(得分:0)

您可以使用变量分配给例如:

 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

检查其他StackO用户发送的其余链接,他们提供了很好的例子! 希望可以帮助您解决问题。 和平!

答案 1 :(得分:0)

有很多收集论点的方法。您可以命名他们的职位,例如$1是第一个参数,$14是第十四个参数。

您可以像$@(保留间距)或$*(收缩间距)那样引用参数列表:

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

由于您仅使用长选项,且将其参数用空格分隔,所以

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

这会循环每个选项并对其进行解析。每个选项都有两个条件,这使我们可以处理参数与选项(--network bobnet)之间的间隔或何时将参数分配给选项(--network=bobnet)。间隔表示我们需要引用下一个参数(因此要加上额外的shift),而分配表示我们需要使用parameter subsitution来删除字符串开头的字符,直到(包括)第一个字符为止=

最后一个shift将第一个项目从参数列表中拉出,以便我们可以对下一个进行操作。分别移动两个参数的子句(而不是以shift 2结尾)还可以使用诸如--verbose之类的二进制选项,其中不包含参数。

您还可以使用while getopts循环来支持短参数和长参数的混合使用。看看我的more detailed post on getopts