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