【问题标题】:Avoiding positional reference in passing parameters in linux shell script and using named parameter在 linux shell 脚本中传递参数和使用命名参数时避免位置引用
【发布时间】:2019-01-28 18:05:24
【问题描述】:

我有一个脚本“/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 脚本中使用这种类型的命名变量。 我已经完成了这个答案Is there a way to avoid positional arguments in bash?,但无法理解如何在我的情况下实施。

【问题讨论】:

标签: linux bash shell


【解决方案1】:

改用环境变量。把你的脚本写成

echo "First arg: $FirstParamPassed"
echo "Second arg: $SecondParamPassed"

然后称它为

FirstParamPassed=1 SecondParamPassed=2 ./SampleScript.sh

SecondParamPassed=2 FirstParamPassed=1 ./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

【讨论】:

    【解决方案2】:

    只是一个简单的解析器:

    #!/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}

    【讨论】:

    • 您可能需要"${i%%=*}" 而不是"${i%=*}" 以匹配以= 开头的最长模式。
    猜你喜欢
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 2010-09-07
    • 1970-01-01
    • 2016-12-17
    相关资源
    最近更新 更多