0

This question already has an answer here:

See edit below, thanks

I have the following test script (important note: I cannot change this part):

while (($#)); do
  echo $1
  shift
done

Running the command ./test aaa "bbbb cccc" ddd gives the following output:

aaa
bbbb cccc
ddd

which is what any sane person would expect.

I have another script:

mode="good"
status="okay"
name="bro"
description="very good man dood"
extra=""

# ----

PARAMS=""

// $1: key, $2: value
function addParam {
    if [ ! -z "$2" ]; then
        PARAMS="$PARAMS --$1 \"$2\""
    fi
}

addParam "mode" "$mode"
addParam "status" "$status"
addParam "name" "$name"
addParam "description" "$description"
addParam "extra" "$extra"

echo ./test $PARAMS
./test $PARAMS

The output from echo is ./test --mode "good" --status "okay" --name "bro" --description "very good man dood", so I would expect the output of ./test $PARAMS to be

--mode
good
--status
okay
--name
bro
--description
very good man dood

but instead, for some reason, I get the following output:

--mode
"good"
--status
"okay"
--name
"bro"
--description
"very
good
man
dood"

If I copy the output of echo ./test $PARAMS and paste it, I get the expected output from ./test. So I tried removing the last line which executes ./test and leave the echo line last, but apparently $(./script) still does not work and I'm beyond ideas.

What am I doing wrong?


Edit: @steeldriver's solution works but there's another constaint - I have to allow users to send their own arguments.

So having this script (thanks @steeldriver):

#!/bin/bash

mode="good"
status="okay"
name="bro"
description="very good man dood"
extra=""
arguments="--config \"blablabla=yes\" --config2 \"bla2=no problem\""

# ----

declare -a PARAMS

# $1: key, $2: value
function addParam {
    if [ ! -z "$2" ]; then
        PARAMS+=("--$1" "$2")
    fi
}

addParam "mode" "$mode"
addParam "status" "$status"
addParam "name" "$name"
addParam "description" "$description"
addParam "extra" "$extra"

# (1)
PARAMS+=("$arguments")

# (2)
PARAMS+=($arguments)

echo ./test "${PARAMS[@]}" 
./test "${PARAMS[@]}"

The desired output is:

--mode
good
--status
okay
--name
bro
--description
very good man dood
--config
blablabla=yes
--config2
bla2=no problem

However the output I get is:

With (1):

--mode
good
--status
okay
--name
bro
--description
very good man dood
--config "blablabla=yes" --config2 "bla2=no problem"

With (2):

--mode
good
--status
okay
--name
bro
--description
very good man dood
--config
"blablabla=yes"
--config2
"bla2=no
problem"

Much appreciated!

marked as duplicate by Gilles shell-script Oct 13 '16 at 21:34

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • @ZacharyBrady Yes, and the result is that the whole string becomes a single argument (i.e., --mode "good" --status "okay" --name "bro" --description "very good man dood" as a single line in the test script) – Adi Gerber Oct 13 '16 at 12:59
1

Use an array rather than a string variable:

#!/bin/bash

mode="good"
status="okay"
name="bro"
description="very good man dood"
extra=""

# ----

declare -a PARAMS

# $1: key, $2: value
function addParam {
    if [ ! -z "$2" ]; then
        PARAMS+=("--$1" "$2")
    fi
}

addParam "mode" "$mode"
addParam "status" "$status"
addParam "name" "$name"
addParam "description" "$description"
addParam "extra" "$extra"

echo ./test "${PARAMS[@]}"
./test "${PARAMS[@]}"

Testing

$ ./other.sh
./test --mode good --status okay --name bro --description very good man dood
--mode
good
--status
okay
--name
bro
--description
very good man dood
  • Thanks, it works! But I actually have another use case which I did not mention because I didn't think it would be necessary. I've edited the question with that use case and what I've tried. – Adi Gerber Oct 13 '16 at 14:09
  • @Adidishen for that, I think your script will need to parse the arguments string into a sequence of tokens that you can pass individually – steeldriver Oct 13 '16 at 15:24
0

Thanks to the heads up from @steeldriver, I managed to add the user arguments properly and get the desired output. This is my script now:

#!/bin/bash

mode="good"
status="okay"
name="bro"
description="very good man dood"
extra=""
arguments="--config \"blablabla=yes\" --config2 \"bla2=no problem\""

# ----

declare -a PARAMS

# $1: key, $2: value
function addParam {
    if [ ! -z "$2" ]; then
        PARAMS+=("--$1" "$2")
    fi
}

# This function right here
function addUserArguments {
    while (($#)); do
      PARAMS+=("$1")
      shift
    done
}

addParam "mode" "$mode"
addParam "status" "$status"
addParam "name" "$name"
addParam "description" "$description"
addParam "extra" "$extra"

# And this line right here
eval addUserArguments $arguments

./test "${PARAMS[@]}"

And the output is

--mode
good
--status
okay
--name
bro
--description
very good man dood
--config
blablabla=yes
--config2
bla2=no problem

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