代码之家  ›  专栏  ›  技术社区  ›  chilltemp

用于接收和重新传递引用参数的Bash脚本

  •  89
  • chilltemp  · 技术社区  · 16 年前

    我试图让嵌套脚本安全地接收bash脚本的引用参数。有什么想法吗?

    test.sh

    #!/bin/bash
    echo $*
    bash myecho.sh $*
    

    #!/bin/bash
     echo $1
     echo $2
     echo $3
     echo $4
    

    样本:

    bash test.sh aaa bbb '"ccc ddd"'
    

    aaa bbb "ccc ddd"
    aaa
    bbb
    "ccc
    ddd"
    

    aaa bbb "ccc ddd"
    aaa
    bbb
    ccc ddd
    
    2 回复  |  直到 16 年前
        1
  •  147
  •   Dave Dopson    9 年前

    您希望使用“$@”(以美元报价)将参数传递给下标。像这样。。。。

    ls-color.sh:

    #!/bin/bash
    /bin/ls --color=auto "$@"    # passes though all CLI-args to 'ls'
    


    至于为什么。。。。。

    Bash man page

    $* 扩展发生在双引号内,它扩展为一个单词 IFS特殊变量。就是, "$*" 相当于 "$1c$2c..." ,其中c是IFS值的第一个字符 变量如果未设置IFS,则参数之间用空格分隔。如果 如果s为null,则在不插入分隔符的情况下连接参数。

    $@ --展开到位置参数,从一开始。什么时候 单独的词。就是, "$@" 相当于 "$1" "$2" ... 如果 双引号展开发生在一个单词中,即 第一个参数与原始参数的开始部分连接 word,最后一个参数的展开式与最后一个参数联接 原词的一部分。如果没有位置参数, $@ 扩展到零(即,它们被删除)。


    echo 'echo -e "\$1=$1\n\$2=$2\n\$3=$3\n\$4=$4"' > echo-params.sh
    echo './echo-params.sh $*' > dollar-star.sh
    echo './echo-params.sh $@' > dollar-at.sh
    echo './echo-params.sh "$*"' > quoted-dollar-star.sh
    echo './echo-params.sh "$@"' > quoted-dollar-at.sh
    chmod +x *.sh
    

    "$@" 身份转换 对于将参数重新传递到子shell(大约99%的情况下,这是您想要做的):

    ./quoted-dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"'
      # $1= aaa
      # $2=            
      # $3= 'cc cc'
      # $4= "ddd ddd"
    

    "$*" -美元星报 if [[ -z "$*" ]]; then ... ):

    ./quoted-dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"'
      # $1= aaa  'cc cc' "ddd ddd"   
      # $2=                     
      # $3=             
      # $4=
    

    $* -如果没有引号,两种形式都会去掉一级引号,并从基础字符串中解释空格,但忽略引号字符(几乎总是这样,这是一个错误):

    ./dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"'
      # $1= aaa
      # $2= 'cc                  
      # $3= cc'
      # $4= "ddd
    
    ./dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"'
      # $1= aaa
      # $2= 'cc
      # $3= cc'
      # $4= "ddd
    

    如果您想玩得开心,可以使用“$@”将东西嵌套到您想要的深度,如果您愿意,可以将元素从args堆栈中推出来或弹出。

    function identity() {
      "$@"
    }
    set -x
    identity identity identity identity identity echo Hello \"World\"
    # + identity identity identity identity identity echo Hello '"World"'
    # + identity identity identity identity echo Hello '"World"'
    # + identity identity identity echo Hello '"World"'
    # + identity identity echo Hello '"World"'
    # + identity echo Hello '"World"'
    # + echo Hello '"World"'
    # Hello "World"
    
        2
  •  72
  •   pixelbeat    16 年前
    #!/bin/bash
    echo $*
    bash myecho.sh "$@"
    

    注意“$@”构造不是特定于bash的,应该与任何POSIX shell一起使用(至少与dash一起使用)。还要注意的是,给定您想要的输出,您根本不需要额外的报价级别。即,只需调用上面的脚本,如下所示:

    ./test.sh 1 2 "3 4"