3

Not critical - but I'm trying to get a deeper understanding of bash scripting and this is driving me crazy!

My goal - in a bash script:

  • Define a function that accepts arguments
  • Set a bash variable (CMD) with the function name & arguments
  • Execute it by $CMD

No problem if there is no whitespace in $args - but here's a minimal script to illustrate:

#!/bin/bash
function tstArgs () {
    echo "In tstArgs: ArgCnt:$#; Arg1:[$1]; Arg2:[$2]"
}
ARG1=today
ARG2=tomorrow
CMD1="tstArgs $ARG1 $ARG2"
$CMD1 #Output - As Desired: In tstArgs: ArgCnt:2; Arg1:[today]; Arg2:[tomorrow]

ARGWS1="'today with spaces'"
ARGWS2="'tomorrow with spaces'"
CMD2="tstArgs $ARGWS1 $ARGWS2"
$CMD2 #Output: In tstArgs: ArgCnt:6; Arg1:[today]; Arg2:[with]

#The dream:
ARGARR=($ARGWS1 $ARGWS2)
CMD3="tstArgs ${ARGARR[@]}"
$CMD3 #Output: In tstArgs: ArgCnt:6; Arg1:[today]; Arg2:[with]
#ETC, ETC, ETC...

This doesn't show the COUNTLESS variations I tried - single quotes, double quotes, escaping quotes, changing IFS, using parameter escape operators ${ARG1@Q}, setting args w. echo XXX - and so much more - way too many to include here, but to be clear, I didn't just jump on stackoverflow without first spending HOURS.

Weirdly, I can use params w. whitespace if I call the function directly:

tstArgs $ARG1 $ARG2
#But no variation of anything like:
CMD="tstArgs $ARG1 $ARG2"
$CMD

I'm sure it must be possible, and probably simple - but it's some permutation I just haven't been able to crack.

Of course I can work around it - but I'm stubborn & persistent & hate to give up. If anyone has any insight, I'd be very grateful, and maybe even finally get some sleep...

2

1 Answer 1

5

Don't put arguments in a string. Put them in an array. Array elements handle spaces much more gracefully:

declare -a ARGS
ARGS+=( "today with spaces" )
ARGS+=( "tomorrow with spaces" )
CMD="tstArgs"
${CMD} "${ARGS[@]}"

Alternatively:

declare -a ARGS
ARGS[0]="today with spaces"
ARGS[1]="tomorrow with spaces"
CMD="tstArgs"
${CMD} "${ARGS[@]}"

Putting quotation marks around ${ARGS[@]} on the last line makes sure that each element of the array is quoted, thus preserving the spaces.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I'm marking this as "accepted" - because there doesn't seem to be an easy way to do what I want with Bash, and it's not a big deal. For reference, my motivation was to create a pattern for multiple bash scripts maintained by multiple developers over multiple years. I've seen way too many things "maintained" by changing code in one part but not another, so I wanted to do something like: CMD=tstArgs $ARG1 $ARG2 #(or whatever) echo "About to execute [$CMD] $CMD

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.