问题
I want to execute a shell script that require 3 arguments.
The argument number 2 contains a string with space
I want to put all arguments in one variable like this:
Linux:~# kk="\"111\" \"222 222\" \"333\""
Linux:~# echo $kk
"111" "222 222" "333"
Now If I call a function:
func() {
echo ---$1---
echo ---$2---
echo ---$3---
}
with the $kk variable in this way
func $kk
Then it will return
Linux:~# func $kk
---"111"---
---"222---
---222"---
And I was expecting to get this result
---111---
---222 222---
---333---
How to solve this issue without using eval
?
I know that the eval
solve this issue but I do not want to use it (since it takes time if I execute many time a such call).
回答1:
OP originally tagged question bash, then removed the tag. Please refer to Charles Duffy's great answer for a POSIX shell solution! the solution below uses arrays and is only suitable for bash.
You should not put your data in a string like this, but in an array. By the way, you're missing some quotes in your function:
func() {
echo "---$1---"
echo "---$2---"
echo "---$3---"
}
or better yet (printf
is preferable to echo
):
func() {
printf -- '---%s---\n' "$1"
printf -- '---%s---\n' "$2"
printf -- '---%s---\n' "$3"
}
$ kk=( "111" "222 222" "333" )
$ func "${kk[@]}"
will happily print:
---111---
---222 222---
---333---
You can even include newlines and such in your arguments:
$ kk=( $'one\none' "222 222" $' * three\nthree' )
$ func "${kk[@]}"
---one
one---
---222 222---
--- * three
three---
回答2:
If features (like arrays) didn't make bash more expressive than POSIX sh, there would have been no reason to add them. :)
That said, you can work around it by overriding "$@"
for your needs:
set -- 111 "222 222" 333
printf '%s\n' "$@"
...will print...
111
222 222
333
If you need to build the arguments list step by step, you can make several calls to set
with "$@"
as the first arguments (make sure you observe the quotes!):
set -- 111
set -- "$@" "222 222"
set -- "$@" 333
printf '%s\n' "$@"
...will print...
111
222 222
333
来源:https://stackoverflow.com/questions/28542911/how-to-put-all-command-arguments-in-one-variable