Linux / Bash:如何取消引用?

以下命令

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可能包含特殊字符,如\"$或反引号。

你确定echoecho $X收到2个参数吗? 对我来说,它收到3.让我们试试:

 X="'ab' 'c'" function f(){ echo $#; echo $1; echo $2; echo $3; } f $X 

显示:

 3 'a b' 'c' 

3个参数是'ab''c' 。 我不认为这是你所期望的。

如果要构建一个多参数变量,请将IFS设置为不会使用的字符(也许是| ),并将其用作变量中的参数分隔符:

 X="ab|c" IFS="|" function f(){ echo $#; echo $1; echo $2; } f $X 

也可以将xargssh -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