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

时间:2021-08-07 18:47:49

I'm writing a bash script where I need to pass a string containing spaces to a function in my bash script.

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

For example:

例如:

#!/bin/bash

myFunction
{
    echo $1
    echo $2
    echo $3
}

myFunction "firstString" "second string with spaces" "thirdString"

When run, the output I'd expect is:

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

firstString
second string with spaces
thirdString

However, what's actually output is:

但是,实际输出的是:

firstString
second
string

Is there a way to pass a string with spaces as a single argument to a function in bash?

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

7 个解决方案

#1


125  

you should put quotes and also, your function declaration is wrong.

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

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

And like the others, it works for me as well. Tell us what version of shell you are using.

和其他人一样,它对我也有用。告诉我们您正在使用的shell版本。

#2


15  

Another solution to the issue above is to set each string to a variable, call the function with variables denoted by a literal dollar sign \$. Then in the function use eval to read the variable and output as expected.

上述问题的另一个解决方案是将每个字符串设置为一个变量,使用由文字美元符号\ $表示的变量调用该函数。然后在函数中使用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

Output is then:

输出是:

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

In trying to solve a similar problem to this, I was running into the issue of UNIX thinking my variables were space delimeted. I was trying to pass a pipe delimited string to a function using awk to set a series of variables later used to create a report. I initially tried the solution posted by ghostdog74 but could not get it to work as not all of my parameters were being passed in quotes. After adding double-quotes to each parameter it then began to function as expected.

在尝试解决类似的问题时,我遇到了UNIX思考我的变量空间分隔的问题。我试图使用awk将管道分隔的字符串传递给函数,以设置稍后用于创建报告的一系列变量。我最初尝试了ghostdog74发布的解决方案,但无法让它工作,因为并非我的所有参数都在引号中传递。在为每个参数添加双引号后,它开始按预期运行。

Below is the before state of my code and fully functioning after state.

下面是我的代码的before状态,并且在状态之后完全正常运行。

Before - Non Functioning Code

之前 - 非功能代码

#!/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

After - Functioning Code

After - 功能代码

#!/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


4  

Your definition of myFunction is wrong. It should be:

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

myFunction()
{
    # same as before
}

or:

要么:

function myFunction
{
    # same as before
}

Anyway, it looks fine and works fine for me on Bash 3.2.48.

无论如何,它看起来很好,并在Bash 3.2.48上工作正常。

#4


3  

The simplest solution to this problem is that you just need to use \" for space separated arguments when running a shell script:

解决此问题的最简单方法是,在运行shell脚本时,您只需要使用\“表示空格分隔的参数:

#!/bin/bash
myFunction() {
  echo $1
  echo $2
  echo $3
}
myFunction "firstString" "\"Hello World\"" "thirdString"

#5


1  

Simple solution that worked for me -- quoted $@

简单的解决方案对我有用 - 引用$ @

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

I could verify the actual grep command (thanks to set -x).

我可以验证实际的grep命令(感谢set -x)。

#6


0  

You could have an extension of this problem in case of your initial text was set into a string type variable, for example:

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

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
}

In this case if you don't pass the status_message variable forward as string (surrounded by "") it will be split in a mount of different arguments.

在这种情况下,如果您没有将status_message变量作为字符串向前传递(由“”包围),它将被拆分为不同参数的安装。

"$variable": The current track is CDE at DEF by ABC

“$ variable”:当前曲目是ABC在DEF的CDE

$variable: The

$ variable:The

#7


-2  

Had the same kind of problem and in fact the problem was not the function nor the function call, but what I passed as arguments to the function.

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

The function was called from the body of the script - the 'main' - so I passed "st1 a b" "st2 c d" "st3 e f" from the command line and passed it over to the function using myFunction $*

函数是从脚本的主体调用的 - 'main' - 所以我从命令行传递“st1 a b”“st2 c d”“st3 e f”并使用myFunction $ *将其传递给函数

The $* causes the problem as it expands into a set of characters which will be interpreted in the call to the function using whitespace as a delimiter.

$ *会导致问题,因为它会扩展为一组字符,这些字符将在使用空格作为分隔符的函数调用中进行解释。

The solution was to change the call to the function in explicit argument handling from the 'main' towards the function : the call would then be myFunction "$1" "$2" "$3" which will preserve the whitespace inside strings as the quotes will delimit the arguments ... So if a parameter can contain spaces, it should be handled explicitly throughout all calls of functions.

解决方案是将显式参数处理中的函数调用从'main'更改为函数:调用将是myFunction“$ 1”“$ 2”“$ 3”,这将保留字符串中的空格,因为引号将分隔参数...因此,如果参数可以包含空格,则应在所有函数调用中显式处理它。

As this may be the reason for long searches to problems, it may be wise never to use $* to pass arguments ...

由于这可能是长时间搜索问题的原因,因此永远不要使用$ *来传递参数......

Hope this helps someone, someday, somewhere ... Jan.

希望这有一天能帮到某个人某个地方......

#1


125  

you should put quotes and also, your function declaration is wrong.

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

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

And like the others, it works for me as well. Tell us what version of shell you are using.

和其他人一样,它对我也有用。告诉我们您正在使用的shell版本。

#2


15  

Another solution to the issue above is to set each string to a variable, call the function with variables denoted by a literal dollar sign \$. Then in the function use eval to read the variable and output as expected.

上述问题的另一个解决方案是将每个字符串设置为一个变量,使用由文字美元符号\ $表示的变量调用该函数。然后在函数中使用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

Output is then:

输出是:

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

In trying to solve a similar problem to this, I was running into the issue of UNIX thinking my variables were space delimeted. I was trying to pass a pipe delimited string to a function using awk to set a series of variables later used to create a report. I initially tried the solution posted by ghostdog74 but could not get it to work as not all of my parameters were being passed in quotes. After adding double-quotes to each parameter it then began to function as expected.

在尝试解决类似的问题时,我遇到了UNIX思考我的变量空间分隔的问题。我试图使用awk将管道分隔的字符串传递给函数,以设置稍后用于创建报告的一系列变量。我最初尝试了ghostdog74发布的解决方案,但无法让它工作,因为并非我的所有参数都在引号中传递。在为每个参数添加双引号后,它开始按预期运行。

Below is the before state of my code and fully functioning after state.

下面是我的代码的before状态,并且在状态之后完全正常运行。

Before - Non Functioning Code

之前 - 非功能代码

#!/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

After - Functioning Code

After - 功能代码

#!/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


4  

Your definition of myFunction is wrong. It should be:

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

myFunction()
{
    # same as before
}

or:

要么:

function myFunction
{
    # same as before
}

Anyway, it looks fine and works fine for me on Bash 3.2.48.

无论如何,它看起来很好,并在Bash 3.2.48上工作正常。

#4


3  

The simplest solution to this problem is that you just need to use \" for space separated arguments when running a shell script:

解决此问题的最简单方法是,在运行shell脚本时,您只需要使用\“表示空格分隔的参数:

#!/bin/bash
myFunction() {
  echo $1
  echo $2
  echo $3
}
myFunction "firstString" "\"Hello World\"" "thirdString"

#5


1  

Simple solution that worked for me -- quoted $@

简单的解决方案对我有用 - 引用$ @

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

I could verify the actual grep command (thanks to set -x).

我可以验证实际的grep命令(感谢set -x)。

#6


0  

You could have an extension of this problem in case of your initial text was set into a string type variable, for example:

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

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
}

In this case if you don't pass the status_message variable forward as string (surrounded by "") it will be split in a mount of different arguments.

在这种情况下,如果您没有将status_message变量作为字符串向前传递(由“”包围),它将被拆分为不同参数的安装。

"$variable": The current track is CDE at DEF by ABC

“$ variable”:当前曲目是ABC在DEF的CDE

$variable: The

$ variable:The

#7


-2  

Had the same kind of problem and in fact the problem was not the function nor the function call, but what I passed as arguments to the function.

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

The function was called from the body of the script - the 'main' - so I passed "st1 a b" "st2 c d" "st3 e f" from the command line and passed it over to the function using myFunction $*

函数是从脚本的主体调用的 - 'main' - 所以我从命令行传递“st1 a b”“st2 c d”“st3 e f”并使用myFunction $ *将其传递给函数

The $* causes the problem as it expands into a set of characters which will be interpreted in the call to the function using whitespace as a delimiter.

$ *会导致问题,因为它会扩展为一组字符,这些字符将在使用空格作为分隔符的函数调用中进行解释。

The solution was to change the call to the function in explicit argument handling from the 'main' towards the function : the call would then be myFunction "$1" "$2" "$3" which will preserve the whitespace inside strings as the quotes will delimit the arguments ... So if a parameter can contain spaces, it should be handled explicitly throughout all calls of functions.

解决方案是将显式参数处理中的函数调用从'main'更改为函数:调用将是myFunction“$ 1”“$ 2”“$ 3”,这将保留字符串中的空格,因为引号将分隔参数...因此,如果参数可以包含空格,则应在所有函数调用中显式处理它。

As this may be the reason for long searches to problems, it may be wise never to use $* to pass arguments ...

由于这可能是长时间搜索问题的原因,因此永远不要使用$ *来传递参数......

Hope this helps someone, someday, somewhere ... Jan.

希望这有一天能帮到某个人某个地方......