将命名参数传递给 shell 脚本

将命名参数传递给 shell 脚本

有没有简单的方法可以将命名参数传递(接收)到 shell 脚本?

例如,

my_script -p_out '/some/path' -arg_1 '5'

并在内部my_script.sh将它们接收为:

# I believe this notation does not work, but is there anything close to it?
p_out=$ARGUMENTS['p_out']
arg1=$ARGUMENTS['arg_1']

printf "The Argument p_out is %s" "$p_out"
printf "The Argument arg_1 is %s" "$arg1"

这在 Bash 或 Zsh 中可能吗?

答案1

如果您不介意被限制为单字母参数名称 ie my_script -p '/some/path' -a5,那么在 bash 中您可以使用内置的getopts,例如

#!/bin/bash

while getopts ":a:p:" opt; do
  case $opt in
    a) arg_1="$OPTARG"
    ;;
    p) p_out="$OPTARG"
    ;;
    \?) echo "Invalid option -$OPTARG" >&2
    exit 1
    ;;
  esac

  case $OPTARG in
    -*) echo "Option $opt needs a valid argument"
    exit 1
    ;;
  esac
done

printf "Argument p_out is %s\n" "$p_out"
printf "Argument arg_1 is %s\n" "$arg_1"

然后你可以做

$ ./my_script -p '/some/path' -a5
Argument p_out is /some/path
Argument arg_1 is 5

有一个有帮助的getopts 小教程或者您可以help getopts在 shell 提示符下键入。

编辑:如果选项没有参数并且后面跟着另一个选项,例如和s 程序,则循环case中的第二个语句将触发。while-pmy_script -p -a5exit

答案2

这不是定位参数的解析器,而是key=value aa=bb参数的解析器;

for ARGUMENT in "$@"
do
   KEY=$(echo $ARGUMENT | cut -f1 -d=)

   KEY_LENGTH=${#KEY}
   VALUE="${ARGUMENT:$KEY_LENGTH+1}"

   export "$KEY"="$VALUE"
done

# use here your expected variables
echo "STEPS = $STEPS"
echo "REPOSITORY_NAME = $REPOSITORY_NAME"
echo "EXTRA_VALUES = $EXTRA_VALUES"

用法

bash args_shell_parser.sh STEPS="ABC" REPOSITORY_NAME="stackexchange" \
           EXTRA_VALUES="KEY1=VALUE1 KEY2=VALUE2"

控制台结果:

STEPS = ABC
REPOSITORY_NAME = stackexchange
EXTRA_VALUES = KEY1=VALUE1 KEY2=VALUE2

特征:

  • 什么都没关系命令论点在
  • 不需要显式声明所有变量
  • 价值观可以有空间
  • 当参数值包含“=”符号时,它处理复杂的情况

将此代码片段放在脚本的开头。

该脚本的先前版本:

答案3

我从那里偷了这个drupal.org,但你可以这样做:

while [ $# -gt 0 ]; do
  case "$1" in
    --p_out=*)
      p_out="${1#*=}"
      ;;
    --arg_1=*)
      arg_1="${1#*=}"
      ;;
    *)
      printf "***************************\n"
      printf "* Error: Invalid argument.*\n"
      printf "***************************\n"
      exit 1
  esac
  shift
done

唯一需要注意的是您必须使用语法my_script --p_out=/some/path --arg_1=5

答案4

我刚刚想出这个脚本

while [ $# -gt 0 ]; do

   if [[ $1 == *"--"* ]]; then
        v="${1/--/}"
        declare $v="$2"
   fi

  shift
done

像这样传递它my_script --p_out /some/path --arg_1 5,然后在脚本中您可以使用$arg_1and $p_out

相关内容