Home > Software design >  Passing quoted aurguments to bash function using a variable
Passing quoted aurguments to bash function using a variable

Time:10-27

I am using bash and trying to do pass quoted arguments to a function using a string variable and it fails.

   myfunc() {
     for myarg in "${@}"
     do
       echo ">$myarg<"
     done
   }
  
   echo "prints three things"
   myfunc foo bar "blah blah"
  
   echo "uugh this prints four... why?!?!?"
   myvar="foo bar \"blah blah\""
   myfunc $myvar

produces this:

prints three things
>foo<
>bar<
>blah blah<
uugh this prints four... why?!?!?
>foo<
>bar<
>"blah<
>blah"<

I am building the list of arguments so that is why I need a string. Also, I am stuck with bash 4.2 version. Is there a way to have the second call to the function behave the same way as the first call?

Note: myvar is being read from a text file so I need that as a string.

CodePudding user response:

Use an array for your arguments.

myvar=(foo bar "blah blah")

myfunc "${myvar[@]}"

You're relying on word splitting with unquoted variable, that's should be fine if the arguments/strings does not contain white spaces or newlines or special character to the shell.

CodePudding user response:

Another option is using zero separated arguments with xargs like this:

myfunc() {
  echo -en $myvar | xargs -I{} -0 echo ">"{}"<"
}

echo "uugh this prints four... why?!?!?"
myvar="foo\0bar\0blah blah\0"
myfunc $myvar

CodePudding user response:

I think I figured it out my own question. The eval command might solve this with the least amount of fuss:

echo "uugh this prints four... why?!?!?"
myvar="foo bar \"blah blah\""
myfunc "$myvar"

eval myfunc $myvar

CodePudding user response:

Using $myvar, the content of the variable gets split on the spaces (this is called word splitting). This results in the four words foo, bar, "blah and blah".

Of course in a real application, you would make myvar an array, where each element contains exactly that string you need to pass.

For example:

myvar=(foo bar "\"blah blah\""  "baz boom") # 4 elements

or whatever you like.

You would expand the array then by

myfunc "${myvar[@]}"
  • Related