Joining bash arguments into single string with spaces
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'
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
update Tl;dr, use
"'${array[*]}'"
To be clear, I don't intend to replicate this answer. I just found there are minor differences to use @
and *
to dereference all values from an array.
Under the hood, $*
and $@
are all arrays, referring to the argv list.
From the question,
I'm trying to join all of the arguments to a Bash function into one single string with spaces separating each argument.
It has 2 sub-questions:
- concatenate the array input arguments into a string.
- pass the concatenated string as a single argument for the shell function.
First, concat array into a string,
array=("$@")
str="'${array[@]}'"
# or
str="'${array[*]}'"
# or
str=\'"${array[*]}"\'
Second, when you pass str
to a function, let's count the number of arguments that function received,
#!/usr/bin/env bash
arr=(a b c d)
function count_args() {
echo '$#' $#
}
count_args "'${arr[@]}'"
count_args \'"${arr[@]}"\'
count_args "'${arr[*]}'"
count_args \'"${arr[*]}"\'
output is
$# 4
$# 4
$# 1
$# 1
only arr[*]
wraps the array into 1 argument for the shell function, why?
Cite from How to use arrays in bash script, which I found it's useful for me,
echo ${array[*]}
echo ${array[@]}
Both syntax let us access all the values of the array and produce the same results, unless the expansion it's quoted. In this case a difference arises: in the first case, when using @, the expansion will result in a word for each element of the array.
Whereas using *
will group the entire array into one single argument during expansion.