I am having some issues with word-splitting in bash variable expansion. I want to be able to store an argument list in a variable and run it, but any quoted multiword arguments aren't evaluating how I expected them to.
I'll explain my problem with an example. Lets say I had a function decho
that printed each positional parameter on it's own line:
#!/bin/bash -u
while [ $# -gt 0 ]; do
echo $1
shift
done
Ok, if I go decho a b "c d"
I get:
[~]$ decho a b "c d"
a
b
c d
Which is what I expect and want. But on the other hand if I get the arguments list from a variable I get this:
[~]$ args='a b "c d"'
[~]$ decho $args
a
b
"c
d"
Which is not what I want. I can go:
[~]$ echo decho $args | bash
a
b
c d
But that seems a little clunky. Is there a better way to make the expansion of $args
in decho $args
be word-split the way I expected?
-
Have you tried:
for arg in "$@" do echo "arg $i:$arg:" let "i+=1" done
Should yield something like:
arg 1: a arg 2: c d
in your case.
Straight from memory, no guarantee :-)
David Dean : This function performs exactly the same as decho. The problem is in calling decho, not decho itself. -
You can use:
eval decho $args
-
hmmm..
eval decho $args
works too:[~]$ eval decho $args a b c d
And I may be able to do something with bash arrays using
"${array[@]}"
(which works like"$@"
), but then I would have to write code to load the array, which would be a pain. -
You can move the eval inside the script:
#!/bin/bash -u eval set -- $* for i; do echo $i; done
Now you can do:
$ args='a b "c d"' $ decho $args a b c d
but you'll have to quote the arguments if you pass them on the CL:
$ decho 'a b "c d"' a b c d
0 comments:
Post a Comment