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.
echo a bb ccc dddd | tr ' ' '\n'
– Mark Hudson Dec 08 '22 at 21:56paste
. – x-yuri Feb 22 '23 at 04:23