代码之家  ›  专栏  ›  技术社区  ›  Grant Limberg

在bash中传递带有空格的字符串作为函数参数

  •  130
  • Grant Limberg  · 技术社区  · 16 年前

    我正在编写一个bash脚本,需要在其中向bash脚本中的函数传递一个包含空格的字符串。

    例如:

    #!/bin/bash
    
    myFunction
    {
        echo $1
        echo $2
        echo $3
    }
    
    myFunction "firstString" "second string with spaces" "thirdString"
    

    运行时,我期望的输出是:

    firstString
    second string with spaces
    thirdString
    

    然而,实际输出是:

    firstString
    second
    string
    

    有没有一种方法可以将带有空格的字符串作为单个参数传递给bash中的函数?

    8 回复  |  直到 6 年前
        1
  •  137
  •   ghostdog74    16 年前

    您应该加引号,而且您的函数声明是错误的。

    myFunction()
    {
        echo "$1"
        echo "$2"
        echo "$3"
    }
    

    和其他人一样,它也适用于我。告诉我们您使用的是什么版本的shell。

        2
  •  17
  •   TheBanjoMinnow    11 年前

    上述问题的另一个解决方案是将每个字符串设置为一个变量,调用变量由文字美元符号表示的函数。 \$ . 然后在函数使用中 eval 按预期读取变量和输出。

    #!/usr/bin/ksh
    
    myFunction()
    {
      eval string1="$1"
      eval string2="$2"
      eval string3="$3"
    
      echo "string1 = ${string1}"
      echo "string2 = ${string2}"
      echo "string3 = ${string3}"
    }
    
    var1="firstString"
    var2="second string with spaces"
    var3="thirdString"
    
    myFunction "\${var1}" "\${var2}" "\${var3}"
    
    exit 0
    

    然后输出:

        string1 = firstString
        string2 = second string with spaces
        string3 = thirdString
    

    在试图解决类似的问题时,我遇到了Unix的问题,我认为我的变量被空间删除了。我试图通过使用 awk 设置一系列稍后用于创建报表的变量。我最初尝试了由ghostdog74发布的解决方案,但由于并不是所有参数都用引号传递,所以无法使其工作。在向每个参数添加双引号后,它开始按预期工作。

    下面是我的代码的前状态和后状态的完全功能。

    before-非功能代码

    #!/usr/bin/ksh
    
    #*******************************************************************************
    # Setup Function To Extract Each Field For The Error Report
    #*******************************************************************************
    getField(){
      detailedString="$1"
      fieldNumber=$2
    
      # Retrieves Column ${fieldNumber} From The Pipe Delimited ${detailedString} 
      #   And Strips Leading And Trailing Spaces
      echo ${detailedString} | awk -F '|' -v VAR=${fieldNumber} '{ print $VAR }' | sed 's/^[ \t]*//;s/[ \t]*$//'
    }
    
    while read LINE
    do
      var1="$LINE"
    
      # Below Does Not Work Since There Are Not Quotes Around The 3
      iputId=$(getField "${var1}" 3)
    done<${someFile}
    
    exit 0
    

    功能后代码

    #!/usr/bin/ksh
    
    #*******************************************************************************
    # Setup Function To Extract Each Field For The Report
    #*******************************************************************************
    getField(){
      detailedString="$1"
      fieldNumber=$2
    
      # Retrieves Column ${fieldNumber} From The Pipe Delimited ${detailedString} 
      #   And Strips Leading And Trailing Spaces
      echo ${detailedString} | awk -F '|' -v VAR=${fieldNumber} '{ print $VAR }' | sed 's/^[ \t]*//;s/[ \t]*$//'
    }
    
    while read LINE
    do
      var1="$LINE"
    
      # Below Now Works As There Are Quotes Around The 3
      iputId=$(getField "${var1}" "3")
    done<${someFile}
    
    exit 0
    
        3
  •  6
  •   kenorb    7 年前

    这个问题最简单的解决方案是你只需要使用 \" 对于运行shell脚本时用空格分隔的参数:

    #!/bin/bash
    myFunction() {
      echo $1
      echo $2
      echo $3
    }
    myFunction "firstString" "\"Hello World\"" "thirdString"
    
        4
  •  5
  •   R Samuel Klatchko    16 年前

    你对MyFunction的定义是错误的。应该是:

    myFunction()
    {
        # same as before
    }
    

    或:

    function myFunction
    {
        # same as before
    }
    

    不管怎样,它看起来很好,在bash 3.2.48上对我来说也很好。

        5
  •  1
  •   Bin TAN - Victor    8 年前

    适用于我的简单解决方案——引用$@

    Test(){
       set -x
       grep "$@" /etc/hosts
       set +x
    }
    Test -i "3 rb"
    + grep -i '3 rb' /etc/hosts
    

    我可以验证实际的grep命令(多亏了set-x)。

        6
  •  1
  •   remykarem yunus    6 年前

    我晚了9年,但更具活力的方式是

    function myFunction 
    {
       for i in $*; do echo $i; done;
    }
    
        7
  •  0
  •   helmedeiros    12 年前

    如果将初始文本设置为字符串类型变量,则可以扩展此问题,例如:

    function status(){    
      if [ $1 != "stopped" ]; then
         artist="ABC";
         track="CDE";
         album="DEF";
         status_message="The current track is $track at $album by $artist";
         echo $status_message;
         read_status $1 "$status_message";
      fi
    }
    
    function read_status(){
      if [ $1 != "playing" ]; then
        echo $2
      fi
    }
    

    在这种情况下,如果不将状态消息变量作为字符串(由“”包围)向前传递,它将被拆分为多个不同的参数。

    “$变量” :当前曲目是ABC在DEF时的CDE

    $变量 :

        8
  •  -2
  •   Jan    12 年前

    有同样的问题,实际上问题不是函数或函数调用,而是我作为参数传递给函数的。

    该函数是从脚本体“main”调用的,因此我从命令行传递了“st1 a b”“st2 c d”“st3 e f”,并使用myfunction将其传递给函数$*

    当它扩展为一组字符时,$*会引起问题,这些字符将在使用空格作为分隔符的函数调用中解释。

    解决方案是将显式参数处理中对函数的调用从“main”改为对函数的调用:然后调用将是MyFunction“$1”“$2”“$3”,它将保留字符串中的空白,因为引号将分隔参数… 因此,如果一个参数可以包含空格,那么应该在所有函数调用中显式地处理它。

    因为这可能是长时间搜索问题的原因,所以最好不要使用$*传递参数…

    希望这能帮助某人,某天,某个地方… 简。

    推荐文章