3

I am interesting in calling some function using dynamically generated arguments in a bash script.

However, if some of the arguments had spaces, it does not seem to work.

Let's have this test script:

#!/bin/bash
# file uu.sh
[[ -z $1 ]] || echo '$1' $1
[[ -z $2 ]] || echo '$2' $2
[[ -z $3 ]] || echo '$3' $3
[[ -z $4 ]] || echo '$4' $4
[[ -z $5 ]] || echo '$5' $5
[[ -z $6 ]] || echo '$6' $6
[[ -z $7 ]] || echo '$7' $7
[[ -z $8 ]] || echo '$8' $8
[[ -z $9 ]] || echo '$9' $9
[[ -z $0 ]] || echo '$0' $0

Any my script:

#!/bin/bash
# file vv.sh
ARR=(-x)
ARR+=($1)
ARR+=("$1")
ARR+=("'$1'")
ARR+=("\"$1\"")
bash uu.sh ${ARR[*]}
echo
bash uu.sh "${ARR[*]}"

When calling bash vv.sh "a b" I get the following result:

$2 -x
$2 a
$3 b
$4 a
$5 b
$6 'a
$7 b'
$8 "a
$9 b"
$0 uu.sh

$1 -x a b a b 'a b' "a b"
$0 uu.sh

I am expecting a way to pass the variables to uu.sh such as the result would be:

$1 -x
$2 a b
$0 uu.sh

(Which I can get directly by calling bash uu.sh -x a\ b, or bash uu.sh -x "a b", or bash uu.sh -x 'a b')

2
  • You want "$1" and not $1. Also you could use "$@" for all args.. Commented Apr 6, 2017 at 17:34
  • The problem is not in uu.sh (and, any how, I tested with the quotation marks, and I still see the same problem) Commented Apr 6, 2017 at 17:38

3 Answers 3

5

You should have vv.sh like this to be able to pass all the arguments after -x in the 2nd argument to uu.sh:

#!/bin/bash
# file vv.sh
ARR=(-x)    # initialize array with "-x" as first element
ARR+=("$1") # append 1st argument in second element of array
bash uu.sh "${ARR[@]}" # call uu.sh with quoted and [@]

Then use it as (see quoted arguments):

bash vv.sh "a b"

...which will emit as output:

$1 -x
$2 a b
$0 uu.sh
Sign up to request clarification or add additional context in comments.

2 Comments

I'm not interested in passing all arguments from vv.sh, just the first argument (or just the third, or some other variable)
However the @ (and quotes) did the trick! bash uu.sh "${ARR[@]}"
3

Here is a difference between $* and $@ and also, you should always quote the variables (unless you know why do not want) :)

#uu.sh
[[ -z "$1" ]] || echo '$1' "$1"
[[ -z "$2" ]] || echo '$2' "$2"
[[ -z "$3" ]] || echo '$3' "$3"
[[ -z "$4" ]] || echo '$4' "$4"
[[ -z "$5" ]] || echo '$5' "$5"
[[ -z "$6" ]] || echo '$6' "$6"
[[ -z "$7" ]] || echo '$7' "$7"
[[ -z "$8" ]] || echo '$8' "$8"
[[ -z "$9" ]] || echo '$9' "$9"
[[ -z "$0" ]] || echo '$0' "$0"

and the vv.sh

ARR=(-x)
ARR+=($1)
ARR+=("$1")
ARR+=("'$1'")
ARR+=("\"$1\"")

echo 'using quoted ARR[@]'
printf "=%s=\n" "${ARR[@]}"

echo 'using unquoted ARR[@]'
printf "=%s=\n" ${ARR[@]}

echo 'using quoted ARR[*]'
printf "=%s=\n" "${ARR[*]}"

echo 'using unquoted ARR[*]'
printf "=%s=\n" ${ARR[*]}

echo "running UU"
bash uu.sh "${ARR[@]}"

output:

using quoted ARR[@]
=-x=
=A=
=B=
=A B=
='A B'=
="A B"=
using unquoted ARR[@]
=-x=
=A=
=B=
=A=
=B=
='A=
=B'=
="A=
=B"=
using quoted ARR[*]
=-x A B A B 'A B' "A B"=
using unquoted ARR[*]
=-x=
=A=
=B=
=A=
=B=
='A=
=B'=
="A=
=B"=
running UU
$1 -x
$2 A
$3 B
$4 A B
$5 'A B'
$6 "A B"
$0 uu.sh

Comments

3

"${array[*]}" and "$*" expand to a single word with the array members or positional parameters joined with spaces. That's almost never useful. Instead, use "${array[@]}" or "$@", which expand all the array members to separate words. (See Arrays and Special parameters in the manual.)

So when you do bash uu.sh "${ARR[*]}" the command is passed one string as parameter, and with bash uu.sh ${ARR[*]} there are no quotes so all contents of the array get split on whitespace.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.