以下命令
echo 'a b' 'c'
输出
a b c
但是以下
X="'a b' 'c'"
echo $X;
将结束
'a b' 'c'
我正在寻找取消引用$ X的方法,以便输出“a b c”,但不会丢失合并的'a b'参数。 (= 2个参数而不是3个,对命令'echo'没有区别,但对于其他命令如'cp'没有区别)
答案 0 :(得分:8)
尝试xargs:
$ echo $x
'a b' 'c'
$ echo $x | xargs ./echo
argc = 3
argv[0] = ./echo
argv[1] = a b
argv[2] = c
答案 1 :(得分:7)
eval echo $x
这会将a b
作为第一个参数传递,将c
作为第二个参数传递
注意:这实际上会评估参数,例如:
$ x='$((3+5))'
$ eval echo $x
8
如果那不是您想要的,请使用@vanza的xargs
。
答案 2 :(得分:2)
通常,如果您尝试在单个变量中存储多个“单词”,建议的方法不是使用嵌入式引号,而是使用数组:
X=('a b' 'c')
printf "%s\n" "${X[@]}"
打印:
a b
c
答案 3 :(得分:0)
这很毛茸茸,我建议解决这个问题,不要在第一时间连接“a b”和“c”。
答案 4 :(得分:0)
X="'a b' 'c'"
echo $X
eval "echo $X"
当您使用此代码时,如果X
可能包含\"$
或反引号等特殊字符,则必须小心。
答案 5 :(得分:0)
您确定echo
在echo $X
中收到了2个参数吗?对我来说,它收到3.让我们试试:
X="'a b' 'c'"
function f(){ echo $#; echo $1; echo $2; echo $3; }
f $X
显示:
3
'a
b'
'c'
3个参数是'a
,b'
和'c'
。我不认为这是你的期望。
如果要构建多参数变量,请将IFS设置为您不会使用的char(可能是|
),并将其用作变量中的参数分隔符:
X="a b|c"
IFS="|"
function f(){ echo $#; echo $1; echo $2; }
f $X
答案 6 :(得分:0)
还可以将xargs
和sh -c 'cmd' _ arg1 arg2 ...
组合到将参数重新分析到位置参数数组$@
中。
将输出分配给变量并将最后一个进程的退出状态$?
重定向到stderr
,例如,可以将最后一个进程的退出代码存储在变量中并在xargs
结束执行后使用它。
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
答案 7 :(得分:0)
请不要将eval用于此类事情。 set
将使echo
以外的参数和命令的完整性保持良好。请记住,您将丢失任何当前位置参数的参考。
set -- "a b" "c"
echo "$@"
#a b c
echo $1
#a b
echo $2
#c