【问题标题】:build argument lists containing whitespace构建包含空格的参数列表
【发布时间】:2010-09-29 12:23:52
【问题描述】:

在 bash 中,可以转义包含空格的参数。

foo "a string"

这也适用于命令或函数的参数:

bar() {
    foo "$@"
}

bar "a string"

到目前为止一切顺利,但如果我想在调用 foo 之前操纵参数怎么办?

这不起作用:

bar() {
    for arg in "$@"
    do
        args="$args \"prefix $arg\""
    done

    # Everything looks good ...
    echo $args

    # ... but it isn't.
    foo $args

    # foo "$args" would just be silly
}

bar a b c

那么当参数包含空格时如何构建参数列表?

【问题讨论】:

    标签: bash arguments whitespace


    【解决方案1】:

    使用arrays(Bash 中的hidden features 之一)。

    【讨论】:

    • 究竟如何?我已经更新了我的问题,尝试使用数组 - 但没有用。
    • 似乎没有一种简单的方法可以将数组传递给函数(实际上是子shell)。您需要引用它们并将它们作为常规参数传递(就像传递给任何其他命令一样)。
    【解决方案2】:

    有(至少)两种方法可以做到这一点:

    1. 使用数组并使用 "${array[@]}" 扩展它:

      bar() {
          local i=0 args=()
          for arg in "$@"
          do
              args[$i]="prefix $arg"
              ((++i))
          done
      
          foo "${args[@]}"
      }
      

      那么,我们学到了什么? "${array[@]}" 是 ${array[*]} "$@" 是 $*。

    2. 或者如果你不想使用数组你需要使用eval:

      bar() {
          local args=()
          for arg in "$@"
          do
              args="$args \"prefix $arg\""
          done
      
          eval foo $args
      }
      

    【讨论】:

    • 该死的,应该早点到这里——本可以省去你的工作:)
    【解决方案3】:

    您可以按照您的建议使用数组,只需更改一个小细节。调用 foo 的行应该是

     foo "${args[@]}"
    

    【讨论】:

      【解决方案4】:

      我也有这个问题。我正在编写一个 bash 脚本来备份我的 Windows 计算机(cygwin)上的重要文件。我也尝试了数组方法,但仍然存在一些问题。不确定我到底是如何修复它的,但这里是我的代码中很重要的部分,以防它对您有所帮助。

      WORK="d:\Work Documents\*"
      #   prompt and 7zip each file
      for x in $SVN $WEB1 $WEB2 "$WORK" $GRAPHICS $W_SQL
      do
          echo "Add $x to archive? (y/n)"
          read DO
          if [ "$DO" == "y" ]; then
              echo "compressing $x"
              7zip a $W_OUTPUT "$x"
          fi
          echo ""
      done
      

      【讨论】:

        【解决方案5】:

        这是一个不需要使用数字索引的较短版本:

        (示例:为find 命令构建参数)

        dir=$1
        shift
        for f in "$@" ; do
            args+=(-iname "*$f*")
        done
        find "$dir" "${args[@]}"
        

        【讨论】:

        • shift 在 Bash 中不能这样工作。它应该是dir=$1; shift。
        • 确实,修好了。
        猜你喜欢
        • 2018-05-30
        • 1970-01-01
        • 2021-05-28
        • 2019-01-01
        • 2022-01-17
        • 2011-10-04
        • 2017-10-28
        • 1970-01-01
        相关资源
        最近更新 更多