【问题标题】:Readonly variable for positional parameter array $@位置参数数组 $@ 的只读变量
【发布时间】:2017-04-15 14:05:23
【问题描述】:

Bash 有一个特殊的变量$@,它将所有发送到脚本或函数的参数存储到一个数组中。如何将此变量的值存储到只读数组中?

假设我有一个脚本/home/jason/bourne

#!/bin/bash

declare -ar Args="$@";

运行它会引发此错误:

$ /home/jason/bourne --help memory;
/home/jason/bourne: line 3: Args: readonly variable

这是语法错误还是 bash 中不可能?


写到一半,我想出了解决方案。我认为这是一个有帮助的问题,所以我会发布它并附上答案。

【问题讨论】:

    标签: bash shell arguments parameter-passing


    【解决方案1】:

    解决方案

    要将"$@" 变量存储为数组,您需要将其用() 包装起来,就像使用文字数组一样。

    #!/bin/bash
    
    declare -ar Args=("$@");
    
    for arg in "${Args[@]}"; do
        echo "${arg}";
    done;
    

    示例输出:

    $ /home/jason/bourne --help memory "quoted phrase";
    --help
    memory
    quoted phrase
    

    注意:$@ 应该始终"" 包裹。 (这条规则可能有一个例外,但至少 99.9% 的时间应该遵循它。) 在这种情况下,请使用 ("$@") 而不是 ($@)

    说明

    要在 bash 中从头开始创建文字数组,您可以这样做:

    declare -ar array=("a" "b" "c d");
    

    "$@" 变量扩展为一个字符串列表,每个字符串都用引号括起来。使用() 包装此列表会将其转换为 bash 数组。

    declare -ar array=("$@");
    

    例如,如果"$@" 扩展为"a" "b" "c d",则("$@") 将变为("a" "b" "c d")

    "$@" == "a" "b" "c d"
    ("$@") == ("a" "b" "c d")
    

    示例

    这是一个并排的代码示例。

    /home/jason/bourne 脚本设置为:

    #!/bin/bash
    
    declare -ar array=("$@");
    for val in "${array[@]}"; do
        echo "${val}";
    done;
    

    会输出这个:

    $ /home/jason/bourne "a" "b" "c d";
    a
    b
    c d
    

    /home/jason/bourne 脚本设置为:

    #!/bin/bash
    
    declare -ar array=("a" "b" "c d");
    for val in "${array[@]}"; do
        echo "${val}";
    done;
    

    会输出同样的东西:

    $ /home/jason/bourne;
    a
    b
    c d
    

    【讨论】:

    • 请注意,(...) 根本不参与扩展。 "$@" 扩展为 inside (...) 的单词序列,(...) 的内容作为元素分配给数组参数。
    • @chepner 很好地抓住了我使用$@ 而不是"$@" 的错误。我添加了一个注释来指出这一点,这样其他人就不会犯同样的错误。
    猜你喜欢
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    相关资源
    最近更新 更多