43

I'm trying to join all of the arguments to a Bash function into one single string with spaces separating each argument. I also need to have the string include single quotes around the whole string.

Here is what I have so far...

$array=("$@")
str="\'"
for arg in "${array[@]}"; do
    let $str=$str+$arg+" "
done
let $str=$str+"\'"

Obviously this does not work but I'm wondering if there is a way to achieve this?

61

I believe that this does what you want. It will put all the arguments in one string, separated by spaces, with single quotes around all:

str="'$*'"

$* produces all the scripts arguments separated by the first character of $IFS which, by default, is a space.

Inside a double quoted string, there is no need to escape single-quotes.

Example

Let us put the above in a script file:

$ cat script.sh 
#!/bin/sh
str="'$*'"
echo "$str"

Now, run the script with sample arguments:

$ sh script.sh one two three four 5
'one two three four 5'

This script is POSIX. It will work with bash but it does not require bash.

A variation: concatenating with slashes instead of spaces

We can change from spaces to another character by adjusting IFS:

$ cat script.sh 
#!/bin/sh
old="$IFS"
IFS='/'
str="'$*'"
echo "$str"
IFS=$old

For example:

$ sh script.sh one two three four       
'one/two/three/four'
  • Okay this worked great and did exactly what I needed. I am trying to use this to change directory to a directory with spaces in the name just by using the arguments. What I ultimately needed this for was to create a function that will change directories without having to type the apostrophes in if the directory has words spaced out. What I just tried was the following: cdm(){ str=" '$*' " cd $str } It only accesses the first argument in str So example: cdm test 2 Result: 'test: No such file or directory – Schwagmister Apr 22 '15 at 3:07
  • @Schwagmister: You can save it into a (string) variable if you want, but, if you don't specifically need to do that, I think cd "$*" will be good enough. – Scott Apr 22 '15 at 6:40
  • @Schwagmister The single quotes are not helpful there. Try: cdm(){ str="$*"; cd "$str"; } or, as Scott suggests, cdm(){ cd "$*"; }. Also, be aware that $* replaces multiple consecutive spaces with a single space. If your directory name may have multiple consecutive spaces or tabs or newlines, then those characters really need to be escaped before they are passed to the cdm function. – John1024 Apr 22 '15 at 6:52
  • So if it is something like test 2 trial 1, how would I make this cd command work correctly? Also this is amazing help I really appreciate it guys. @Scott – Schwagmister Apr 22 '15 at 7:08
  • @Schwagmister The best way is to put single-quotes on the command line when calling cdm as in: cdm 'test 2 trial 1'. This will handle all manor of strange names. However, as long as the white spaces are limited to single-spaces, then the cdm then it can be run as cdm test 2 trial 1. – John1024 Apr 22 '15 at 7:23
6

It's easier than you think:

#!/bin/bash
array="${@}"

echo $array

chmod +x that, and run it:

$ ./example.sh --foo bar -b az 
--foo bar -b az

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.