47

I'm trying to pass multiple argument to a function, but one of them is consist of two words and I want shell function to deal with it as one arg:

args=("$@")
function(){
 echo ${args[0]}
 echo ${args[1]}
 echo ${args[2]}
}

when I call this command sh shell hi hello guys bye

I get this

hi

hello

guys

But what I really want is:

hi 
hello guys
bye
Soroush
  • 103
  • 3
user78050
  • 1,045
  • 2
  • 11
  • 16
  • You shouldn't use `function` as a name of a function. It's a keyword in `ksh`, and some bourne-shell like `bash`, `zsh`, `dash`. – cuonglm Aug 23 '14 at 18:31
  • @Gnouc. Not in `dash`. In `yash` yes. Though `zsh` also accepts `ksh`'s function definition syntax, `function() echo x; function` will work in `zsh`. So the only shells where that is a problem are `ksh`, `bash` and `yash`. – Stéphane Chazelas Aug 23 '14 at 20:05
  • @StéphaneChazelas: Oh, I retry and it works in `zsh`, but `dash` doesn't. – cuonglm Aug 23 '14 at 20:13

2 Answers2

32

You should just quote the second argument.

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

myfunc hi "hello guys" bye
sillyMunky
  • 464
  • 3
  • 5
15

It is the same as calling anything (a shell script, a C program, a python program, …) from a shell

If calling from any Unix shell, and the parameter has spaces, then you need to quote it.

sh my-shell-script hi "hello guys" bye

You can also use single quotes, these are more powerful. They stop the shell from interpreting anything ($, !, \, *, ", etc, except ')

sh my-shell-script hi 'hello guys' bye

You should also quote every variable used within the function/script.

Note that in your example the arguments are falling apart before they get to the function (as they are passed to the script).

#!/bin/sh
my_procedure{
   echo "$1"
   echo "$2"
   echo "$3"
}
my_procedure("$@")

There is no way to do it automatically, in the script, as there is no way for the script to know which spaces are which (which words are together).

ctrl-alt-delor
  • 27,473
  • 9
  • 58
  • 102