【问题标题】:Using "read" to set variables使用“读取”设置变量
【发布时间】:2016-02-14 05:24:16
【问题描述】:

在 CLI 的 bash 中,我可以做到:

$ ERR_TYPE=$"OVERLOAD"
$ echo $ERR_TYPE
OVERLOAD
$ read ${ERR_TYPE}_ERROR
1234
$ echo $OVERLOAD_ERROR
1234

这非常适合动态设置我的变量名;在脚本中它不起作用。我试过了:

#!/bin/env bash

ERR_TYPE=("${ERR_TYPE[@]}" "OVERLOAD" "PANIC" "FATAL")

for i in "${ERR_TYPE[@]}"
do
   sh -c $(echo ${i}_ERROR=$"1234")
done
echo $OVERLOAD_ERROR # output is blank

   # I also tried these:
   # ${i}_ERROR=$(echo ${i}_ERROR=$"1234") # command not found
   # read ${i}_ERROR=$(echo ${i}_ERROR=$"1234") # it never terminates

如何像在 CLI 中那样设置变量,但在脚本中?谢谢

【问题讨论】:

    标签: linux macos bash variables


    【解决方案1】:

    当您使用动态变量名称而不是关联数组时,您确实需要质疑您的方法。

    err_type=("OVERLOAD" "PANIC" "FATAL")
    declare -A error
    for type in "${err_type[@]}"; do
        error[$type]=1234
    done
    

    尽管如此,在 bash 中你会使用 declare:

    declare "${i}_error=1234"
    

    您的方法失败了,因为您生成了一个新的 shell,传递了命令 OVERLOAD_ERROR=1234,然后 shell 退出了。您当前的外壳完全不受影响。

    改掉使用 ALLCAPSVARNAMES 的习惯。有一天你会写PATH=...,然后想知道为什么你的脚本坏了。

    【讨论】:

    • 关于declare函数与eval,后者是不是真的打算用它来设置变量? S. Klumpers 方法有效,但我还没有接受答案,因为我想确定一下。谢谢!,哎呀,我的意思是谢谢! (ALLCAPS=没有指出好的做法)...
    • eval 旨在将字符串评估为 shell 代码,而不是专门针对变量。 declare 旨在创建变量,可能具有某种属性(如关联/索引数组、整数、小写等)
    【解决方案2】:

    如果变量包含一个数字,您可以使用let

    #!/bin/bash
    
    ERR_TYPE=("OVERLOAD" "PANIC" "FATAL")
    
    j=0
    for i in "${ERR_TYPE[@]}"
    do
      let ${i}_ERROR=1000+j++
    done
    echo $OVERLOAD_ERROR
    echo $PANIC_ERROR
    echo $FATAL_ERROR
    

    这个输出:

    1000
    1001
    1002
    

    【讨论】:

    • 我附加的部分可以是数字或字符串。不过感谢您的回答,我之前不知道 let - 很高兴知道它是用于数字的。
    【解决方案3】:

    我会使用eval。 我认为这会被认为是不好的做法(这与 eval 是“邪恶的”这一事实有关,因为它允许错误的输入或其他东西):

    eval "${i}_ERROR=1234"
    

    【讨论】:

    • 我修复了它,如果有疑问,只需添加更多 eval。
    • 嘿,看看你!您将永远被称为“伊娃博士!”! :D ...是的,它有效...但就像你说的那样,这是正确的方法吗?即使它正在工作,或者它是如何工作的以及为什么工作,我还是有点紧张。如果可以在 while 循环中使用“读取”,我也不介意......只是我对 while 循环不够熟悉,并且阅读我可以让它以任何原因终止。如果无法完成,这是我很乐意接受您的回答的唯一方法...再次感谢
    • eval 命令通过计算所有表达式并返回结果来工作,echo 将其打印出来,因为它位于一个子shell 中,将成为下一个 eval 的参数。
    • 您可以循环读取,但要使动态变量正常工作,它需要再次使用这个技巧。
    • eval 一点也不邪恶……只有 eval 的错误用法才是邪恶的。很抱歉,但这个答案很糟糕。至少,使用eval "${i}_ERROR=1234"
    猜你喜欢
    • 2014-05-08
    • 2022-08-04
    • 1970-01-01
    • 2014-07-20
    • 2021-06-02
    • 2017-08-22
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多