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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1983048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:49:10  来源:igfitidea点击:

Passing a string with spaces as a function argument in bash

bashfunction

提问by Grant Limberg

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 
    echo 
    echo 
}

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 中的函数?

回答by ghostdog74

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

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

myFunction()
{
    echo ""
    echo ""
    echo ""
}

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

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

回答by TheBanjoMinnow

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 evalto read the variable and output as expected.

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

#!/usr/bin/ksh

myFunction()
{
  eval string1=""
  eval string2=""
  eval string3=""

  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 awkto 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 - Non Functioning Code

之前 - 非功能代码

#!/usr/bin/ksh

#*******************************************************************************
# Setup Function To Extract Each Field For The Error Report
#*******************************************************************************
getField(){
  detailedString=""
  fieldNumber=

  # 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

后 - 功能代码

#!/usr/bin/ksh

#*******************************************************************************
# Setup Function To Extract Each Field For The Report
#*******************************************************************************
getField(){
  detailedString=""
  fieldNumber=

  # 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

回答by Piyush Aggarwal

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 
  echo 
  echo 
}
myFunction "firstString" "\"Hello World\"" "thirdString"

回答by R Samuel Klatchko

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 上对我来说效果很好。

回答by Raimi bin Karim

I'm 9 years late but a more dynamic way would be

我迟到了 9 年,但更有活力的方式是

function myFunction {
   for i in "$*"; do echo "$i"; done;
}

回答by Bin TAN - Victor

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)。

回答by helmedeiros

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 [  != "stopped" ]; then
     artist="ABC";
     track="CDE";
     album="DEF";
     status_message="The current track is $track at $album by $artist";
     echo $status_message;
     read_status  "$status_message";
  fi
}

function read_status(){
  if [  != "playing" ]; then
    echo 
  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

回答by Jan

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.

希望这可以帮助某人,有一天,某个地方...... Jan。