代码之家  ›  专栏  ›  技术社区  ›  Miroslav Popov

如何在Bash中为脚本提供一个魔术变量

  •  1
  • Miroslav Popov  · 技术社区  · 5 年前

    如何给脚本一个魔术变量(占位符)?

    让我们来一个 loop 脚本:

    #!/bin/bash
    
    count=$1
    shift
    
    for i in $(seq 1 $count)
    do
        $*
    done
    
    

    我想这样称呼它:

    loop 5 echo Mambo number $i

    但是,Bash在脚本调用之前扩展变量并生成:

    Mambo number
    Mambo number
    Mambo number
    Mambo number
    Mambo number
    

    如果我这样称呼它:

    loop 5 echo Mambo number '$i'

    Mambo number $i
    Mambo number $i
    Mambo number $i
    Mambo number $i
    Mambo number $i
    

    有没有在bash中使用魔术变量的聪明方法?

    我希望实现:

    Mambo number 1
    Mambo number 2
    Mambo number 3
    Mambo number 4
    Mambo number 5
    

    loop 3 touch 'foo-$i.log'

    要创建三个文件:

    foo-1.log
    foo-2.log
    foo-3.log
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   thanasisp Anthony Battaglia    5 年前

    看来你想评估一下你的论点

    #!/bin/bash
        
    count=$1
    shift
        
    for i in $(seq 1 $count)
    do
        eval "$@"
    done
    

    bash loop.sh 3 echo test '"$i"'
    test 1
    test 2
    test 3
    

    或者最好将单引号中的整个字符串保护为一个字符串参数

    bash loop.sh 3 'echo "$i" "$((i+1))"  $(bc -l <<< "$i+2")'
    1 2 3
    2 3 4
    3 4 5
    

    小心点。

        2
  •  1
  •   user414777    5 年前

    1. ${!varname} “间接膨胀”形式,不可移植到其他外壳

    2. eval ,它是可移植的,而且更加通用和明显,但是会让一些不太理想的人检查您的代码时遇到麻烦;-)

    所以,我将给出一个可能的解决方案。

    loop(){
       local i cnt=$1 cmd=$2 arg=$3
       for((i=0;i<cnt;i++)); do "$cmd" "${!arg}"; done 
    }
    mambo(){
       printf '%s ' mambo nr "$@"; echo
    }
    loop 6 mambo i
    mambo nr 0
    mambo nr 1
    mambo nr 2
    mambo nr 3
    mambo nr 4
    mambo nr 5
    
    推荐文章