【问题标题】:Assigning default values to shell variables with a single command in bash在 bash 中使用单个命令为 shell 变量分配默认值
【发布时间】:2011-01-02 01:58:18
【问题描述】:

我在 bash (3.00) shell 脚本中对变量进行了一大堆测试,如果没有设置变量,那么它会分配一个默认值,例如:

if [ -z "${VARIABLE}" ]; then 
    FOO='default'
else 
    FOO=${VARIABLE}
fi

我似乎记得有一些语法可以在一行中执行此操作,类似于三元运算符,例如:

FOO=${ ${VARIABLE} : 'default' }

(虽然我知道那行不通……)

我是疯了,还是有类似的事情存在?

【问题讨论】:

标签: bash shell


【解决方案1】:

对于命令行参数:

VARIABLE="${1:-$DEFAULTVALUE}"

它将传递给脚本的第一个参数的值分配给VARIABLE,如果没有传递这样的参数,则分配DEFAULTVALUE的值。引用可以防止通配符和分词。

【讨论】:

    【解决方案2】:

    实际上与您发布的内容非常接近。您可以使用名为 Bash parameter expansion 的东西来完成此操作。

    要获取分配的值,或者default(如果缺少):

    FOO="${VARIABLE:-default}"  # If variable not set or null, use default.
    # If VARIABLE was unset or null, it still is after this (no assignment done).
    

    或者将default同时赋值给VARIABLE

    FOO="${VARIABLE:=default}"  # If variable not set or null, set it to default.
    

    【讨论】:

    • 如果我想在文档中找到这个,谷歌会做什么?使用 ${:-} 等特殊字符进行谷歌搜索并不容易。
    • 请注意,它是not bash-specific,适用于整个 shell 系列。通用脚本是安全的。
    • @solarmist 关键字是“bash 参数扩展”,如果您想了解更多关于它及其同伴的信息。
    • 这里对unix.stackexchange.com/a/122848/2407这个话题有更深入的解释
    【解决方案3】:

    见3.5.3(shell参数扩展)下的here

    在你的情况下

    ${VARIABLE:-default}
    

    【讨论】:

      【解决方案4】:

      还有一种更简洁地表达“if”结构的方法:

      FOO='default'
      [ -n "${VARIABLE}" ] && FOO=${VARIABLE}
      

      【讨论】:

        【解决方案5】:

        即使你可以像默认值一样使用另一个变量的值

        有一个文件defvalue.sh

        #!/bin/bash
        variable1=$1
        variable2=${2:-$variable1}
        
        echo $variable1
        echo $variable2
        

        运行./defvalue.sh first-value second-value输出

        first-value
        second-value
        

        然后运行./defvalue.sh first-value 输出

        first-value
        first-value
        

        【讨论】:

          【解决方案6】:

          如果变量相同,那么

          : "${VARIABLE:=DEFAULT_VALUE}"
          

          如果未定义,则将 DEFAULT_VALUE 分配给 VARIABLE。双引号可防止通配符和分词。

          另请参阅 Bash 手册中的第 3.5.3 节,Shell Parameter Expansion

          【讨论】:

          • 这个棘手的技巧对我来说并不明显,使用 : no-effect builtin 来吃 ${..} 的扩展但留下 VARIABLE 集。到目前为止,我一直在这样做: VARIABLE="${VARIABLE:-DEFAULT_VALUE}" 并且因为使用 VARIABLE 两次而感到愚蠢。
          • 事实证明这并不总是适用于 BASH 内置变量。这非常非常奇怪。目前我知道的是HISTTIMEFORMAT
          • 如何设置多个默认值?我试过 ": ${VARIABLE:=DEFAULT_VALUE} : ${VARIABLE2:=DEFAULT_VALUE2}" 但这似乎不起作用......
          • @Hans:冒号是命令(什么都不做),因此只需要一次。例如。 : ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
          • 有机会在export 中使用类似的东西吗?我想让这个变量可用于从当前脚本调用的脚本。
          【解决方案7】:

          这是一个例子

          #!/bin/bash
          
          default='default_value'
          value=${1:-$default}
          
          echo "value: [$value]"
          

          将其保存为 script.sh 并使其可执行。 不带参数运行它

          ./script.sh
          > value: [default_value]
          

          使用参数运行它

          ./script.sh my_value
          > value: [my_value]
          

          【讨论】:

            【解决方案8】:

            FWIW,您可以提供如下错误消息:

            USERNAME=${1:?"Specify a username"}
            

            这会显示这样的消息并以代码 1 退出:

            ./myscript.sh
            ./myscript.sh: line 2: 1: Specify a username
            

            一个更完整的例子:

            #!/bin/bash
            ACTION=${1:?"Specify 'action' as argv[1]"}
            DIRNAME=${2:-$PWD}
            OUTPUT_DIR=${3:-${HOMEDIR:-"/tmp"}}
            
            echo "$ACTION"
            echo "$DIRNAME"
            echo "$OUTPUT_DIR"
            

            输出:

            $ ./script.sh foo
            foo
            /path/to/pwd
            /tmp
            
            $ export HOMEDIR=/home/myuser
            $ ./script.sh foo
            foo
            /path/to/pwd
            /home/myuser
            
            • $ACTION 取第一个参数的值,如果为空则退出
            • $DIRNAME是第二个参数,默认为当前目录
            • $OUTPUT_DIR 是第三个参数,或 $HOMEDIR(如果已定义),否则为 /tmp。这适用于 OS X,但我不确定它是否可移植。

            【讨论】:

              【解决方案9】:

              回答您的问题和所有变量替换

              echo "${var}"
              echo "Substitute the value of var."
                  
              
              echo "${var:-word}"
              echo "If var is null or unset, word is substituted for var. The value of var does not change."
                  
              
              echo "${var:=word}"
              echo "If var is null or unset, var is set to the value of word."
                  
              
              echo "${var:?message}"
              echo "If var is null or unset, message is printed to standard error. This checks that variables are set correctly."
                  
              
              echo "${var:+word}"
              echo "If var is set, word is substituted for var. The value of var does not change."
              

              您可以通过在美元符号和表达式的其余部分之间放置一个 \ 来转义整个表达式。

              echo "$\{var}"
              

              【讨论】:

              • 还有{var-default},其中default 仅在var 未定义时使用。如果定义了var 但为空,则不会使用default
              • 为什么每行都有一个反斜杠?其他答案没有。
              猜你喜欢
              • 1970-01-01
              • 2013-04-25
              • 2019-09-18
              • 2021-06-11
              • 1970-01-01
              • 2018-02-02
              相关资源
              最近更新 更多