【问题标题】:Variable substitution in a for-loop using {$var}使用 {$var} 在 for 循环中进行变量替换
【发布时间】:2011-03-27 04:48:13
【问题描述】:

我对 bash 脚本非常陌生,我正在尝试通过制作这个只要求一系列数字的小脚本来练习。我会进入前。 5..20 并且它应该打印范围,但是 - 它只是回显我输入的任何内容(在本例中为“5..20”)并且不会扩展变量。谁能告诉我我做错了什么?

脚本:

    echo -n "Enter range of number to display using 0..10 format: "
    read range

    function func_printrage
    {
         for n in {$range}; do
         echo $n
         done
    }

func_printrange

【问题讨论】:

    标签: bash


    【解决方案1】:
    1. bash 中的大括号扩展不会扩展参数(与 zsh 不同)
    2. 您可以通过使用eval 和命令替换$() 来解决这个问题
    3. eval 是邪恶的,因为你需要清理你的输入,否则人们可以输入像rm -rf /; 这样的范围,eval 会运行它
    4. 不要使用 function 关键字,它不是 POSIX 并且已被弃用
    5. 使用read-p 标志代替echo

    但是,出于学习目的,您可以这样做:

    read -p "Enter range of number to display using 0..10 format: " range
    
    func_printrange()
    {
      for n in $(eval echo {$range}); do
        echo $n
      done
    }
    
    func_printrange
    

    注意:在这种情况下,使用eval 是可以的,因为你只是echo'ing 范围

    【讨论】:

    • 谢谢,现在可以使用了!使用“功能”有什么问题?我应该使用其他替代方法吗?
    • @ZDRuX: function 不是 POSIX,即它不是可移植的。至于替代方案,请参阅我的代码。
    • 这种使用 eval 绝对不安全。尝试输入1..5 $(ls)
    【解决方案2】:

    一种方法是使用eval, 粗略的例子,

    for i in $(eval echo {0..$range}); do echo $i; done
    

    另一种方法是使用bash的C风格for循环

    for((i=1;i<=20;i++))
    do
      ...
    done
    

    最后一个比第一个更快(例如,如果您的 $range > 1 000 000)

    【讨论】:

    • 你不能用这种方式替换变量:...;i&lt;=$var;...
    • @karatedog 正确,但您并没有真正提供帮助。正确的用法是使用不带$前缀的变量名:for ((i=begin;i&lt;=end;i++); do echo $i; done
    【解决方案3】:

    解决扩展不足并跳过 eval 问题的一种方法是使用命令替换和 seq。

    重做的函数(也避免了全局变量):

    function func_print_range
    {
         for n in $(seq $1 $2); do
         echo $n
         done
    }
    
    func_print_range $start $end
    

    【讨论】:

      【解决方案4】:

      使用${} 进行变量扩展。在您的情况下,它将是 ${range}。您在 ${} 中省略了 $,它用于变量扩展和替换。

      【讨论】:

      • 感谢您的评论,但是 - 我不想在子 shell 中执行命令。我想将 $range 变量替换为“for n in”循环,所以基本上它变成:“for n in {5..20}; do”
      • @ZDRuX 啊,我明白了,更正了我的答案。您忘记了 $ 来启动变量扩展。
      • -1,这不能回答问题。他说的是大括号扩展而不是变量扩展
      猜你喜欢
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      • 2012-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-07
      相关资源
      最近更新 更多