在linux shell脚本中传递参数和使用命名参数时避免位置引用

在linux shell脚本中传递参数和使用命名参数时避免位置引用,linux,bash,shell,Linux,Bash,Shell,我有一个脚本“/tmp/SampleScript.sh”,包含以下内容: echo "First arg: $1" echo "Second arg: $2" 如果我按如下方式运行此脚本: [oracle@xxxxx tmp]$ ./SampleScript.sh FirstParamPassed SecondParamPassed Output Is: First arg: FirstParamPassed Second arg: SecondParamPassed 但如果我将其作为: [

我有一个脚本“/tmp/SampleScript.sh”,包含以下内容:

echo "First arg: $1"
echo "Second arg: $2"
如果我按如下方式运行此脚本:

[oracle@xxxxx tmp]$ ./SampleScript.sh FirstParamPassed SecondParamPassed
Output Is:
First arg: FirstParamPassed
Second arg: SecondParamPassed
但如果我将其作为:

[oracle@xxxxx tmp]$ ./SampleScript.sh SecondParamPassed FirstParamPassed
Output Is:
First arg: SecondParamPassed
Second arg: FirstParamPassed
我想要这样的输出:

echo "First arg: $FirstParamPassed"
echo "Second arg: $FirstParamPassed"
[oracle@xxxxx tmp]$ ./SampleScript.sh SecondParamPassed=2 FirstParamPassed=1
First arg: 1
Second arg: 2
如何在REHL shell脚本中使用这种类型的命名变量。 我已经回答了这个问题,但无法理解如何在我的情况下实现。

只是一个简单的解析器:

#!/bin/bash
for i; do  # this is shorter form of `for i in "$@"`

        case "${i%=*}" in
        a|b|c) ;;
        *) echo "ERROR: unknown variable name '${i%=*}' passed. Only 'a', 'b' and 'c' are supported." >&2; exit 1; ;;
        esac

        declare "$i"
done
echo a="$a"
echo b="$b"
echo c="$c"
例如:

> ./1.sh a=1 b=2 c='!! @@ ## $$ '\''$(echo 123)'\''$(echo 123)'3
a=1
b=2
c=!! @@ ## $$ '$(echo 123)'$(echo 123)3
@编辑

我添加了一个简单的检查变量名
“${I%=*}”
是否是所需的变量之一。也不需要在
=
上拆分
${i}

使用环境变量。将脚本编写为

echo "First arg: $FirstParamPassed"
echo "Second arg: $SecondParamPassed"
那就称它为

FirstParamPassed=1 SecondParamPassed=2 ./SampleScript.sh

预命令分配的顺序并不重要

如果在调用脚本之前启用了
-k
选项,则可以将赋值放在脚本之后,模仿您最初的尝试

$ set -k
$ ./SampleScript.sh SecondParamPassed=2 FirstParamPassed=1
First arg: 1
Second arg: 2
同样,作业的顺序并不重要


您也可以修改脚本,以允许通过位置参数设置值。仅当尚未设置环境变量时,才会使用位置参数

: ${FirstParamPassed:=$1}
: ${SecondParamPassed:=$2}
echo "First arg: $FirstParamPassed"
echo "Second arg: $SecondParamPassed"
比如说,

$ SecondParamPassed=2 ./SampleScript.sh 6 notused
First arg: 6
Second arg: 2

下面是一个类似的SO问题的另一个更简单的答案,它可能比您提到的SO问题更容易适应:您可能想要
“${i%%=*}”
而不是
“${i%=*}”
,以便匹配从
=
开始的最长模式。
$ SecondParamPassed=2 ./SampleScript.sh 6 notused
First arg: 6
Second arg: 2