Linux/Bash: How to unquote?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6988288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Linux/Bash: How to unquote?
提问by Daniel Marschall
Following command
Following command
echo 'a b' 'c'
outputs
outputs
a b c
But the following
But the following
X="'a b' 'c'"
echo $X;
will outout
will outout
'a b' 'c'
I am searching a way to unquote $X , so that it will output "a b c" , but without losing the merged 'a b' argument. (= 2 arguments instead of 3, makes no difference for command 'echo', but for other commands like 'cp')
I am searching a way to unquote $X , so that it will output "a b c" , but without losing the merged 'a b' argument. (= 2 arguments instead of 3, makes no difference for command 'echo', but for other commands like 'cp')
采纳答案by vanza
Try xargs:
Try xargs:
$ echo $x
'a b' 'c'
$ echo $x | xargs ./echo
argc = 3
argv[0] = ./echo
argv[1] = a b
argv[2] = c
回答by Karoly Horvath
eval echo $x
this will pass a bas first argument and cas the second one
this will pass a bas first argument and cas the second one
Note: this will actually evaluate arguments, eg:
Note: this will actually evaluate arguments, eg:
$ x='$((3+5))'
$ eval echo $x
8
If that's not what you want use @vanza's xargs.
If that's not what you want use @vanza's xargs.
回答by Gordon Davisson
Usually, if you're trying to store multiple "words" in a single variable, the recommended method isn't to use embedded quotes, but to use an array:
Usually, if you're trying to store multiple "words" in a single variable, the recommended method isn't to use embedded quotes, but to use an array:
X=('a b' 'c')
printf "%s\n" "${X[@]}"
prints:
prints:
a b
c
回答by larzq
It is also possible to combine xargsand sh -c 'cmd' _ arg1 arg2 ...to reparse arguments into the positional parameter array $@.
It is also possible to combine xargsand sh -c 'cmd' _ arg1 arg2 ...to reparse arguments into the positional parameter array $@.
Assigning the output to a variable and redirecting anything but the exit status $?of the last process to stderr, for example, makes it possible to store the exit code of the last process in a variable and use it after xargshas ended execution.
Assigning the output to a variable and redirecting anything but the exit status $?of the last process to stderr, for example, makes it possible to store the exit code of the last process in a variable and use it after xargshas ended execution.
X="'a b' 'c'"
ret="$(
export IFS=''
set -o pipefail
echo $X | xargs sh -c '
for file in "$@"; do
echo cp "$file" destdir 1>&2 || { echo $?; kill -HUP $PPID; exit $?; }
#(exit 3) || { echo $?; kill -HUP $PPID; exit $?; }
#(exit 3) || { echo $?; kill -HUP $PPID; kill -HUP -- -$$; }
done
echo $?
' _
echo $? '|' ${PIPESTATUS[@]} 1>&2
)"
echo "$ret" | tail -1
回答by user.friendly
Please don't use eval for something like this. setwill keep the integrity of the parameters and commands other than echowill play nicely with them. Just keep in mind you'll lose the reference(s) to any current positional parameters.
Please don't use eval for something like this. setwill keep the integrity of the parameters and commands other than echowill play nicely with them. Just keep in mind you'll lose the reference(s) to any current positional parameters.
set -- "a b" "c"
echo "$@"
#a b c
echo
#a b
echo
#c
回答by Roland Illig
X="'a b' 'c'"
echo $X
eval "echo $X"
When you use this code you have to be careful if Xcan possibly contain special characters like \"$or backticks.
When you use this code you have to be careful if Xcan possibly contain special characters like \"$or backticks.
回答by jfg956
Are you sure echoreceives a 2 parameters in echo $X? For me, it receives 3. Lets try:
Are you sure echoreceives a 2 parameters in echo $X? For me, it receives 3. Lets try:
X="'a b' 'c'"
function f(){ echo $#; echo ; echo ; echo ; }
f $X
displays:
displays:
3
'a
b'
'c'
The 3 parameters are 'a, b'and 'c'. I do not think it is what you expect.
The 3 parameters are 'a, b'and 'c'. I do not think it is what you expect.
If you want to build a multi parameter variable, set IFS to a char you will not use (maybe |), and use it as a parameter delimiter in your variable:
If you want to build a multi parameter variable, set IFS to a char you will not use (maybe |), and use it as a parameter delimiter in your variable:
X="a b|c"
IFS="|"
function f(){ echo $#; echo ; echo ; }
f $X
回答by C. Ramseyer
This is hairy, I'd recommend working around the issue and don't concatenate "a b" and "c" in the first place.
This is hairy, I'd recommend working around the issue and don't concatenate "a b" and "c" in the first place.

