Linux/Bash:如何取消引用?
Posted
技术标签:
【中文标题】Linux/Bash:如何取消引用?【英文标题】:Linux/Bash: How to unquote? 【发布时间】:2011-10-22 17:31:17 【问题描述】:以下命令
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')
【问题讨论】:
回声 $X//\'/; // a b c 【参考方案1】:试试 xargs:
$ echo $x
'a b' 'c'
$ echo $x | xargs ./echo
argc = 3
argv[0] = ./echo
argv[1] = a b
argv[2] = c
【讨论】:
注意:xargs 不能返回进程的退出状态。任何错误 1-125 都将显示为 123。(可能没有可用的解决方法)我可能会使用 eval 代替,以便能够使用 exitcode 这个答案对我有帮助,但我一开始并没有得到它。这是我使用的:echo $x | xargs -n1 echo
输出:a b c【参考方案2】:
eval echo $x
这会将a b
作为第一个参数,c
作为第二个参数
注意:这实际上会评估参数,例如:
$ x='$((3+5))'
$ eval echo $x
8
如果这不是您想要的,请使用@vanza 的xargs
。
【讨论】:
谢谢。我还没有使用“eval”,但根据脚本注入,xargs 似乎更安全。【参考方案3】:通常,如果您尝试在单个变量中存储多个“单词”,推荐的方法不是使用嵌入式引号,而是使用数组:
X=('a b' 'c')
printf "%s\n" "$X[@]"
打印:
a b
c
【讨论】:
【参考方案4】:X="'a b' 'c'"
echo $X
eval "echo $X"
当您使用此代码时,您必须小心X
是否可能包含特殊字符,例如\"$
或反引号。
【讨论】:
【参考方案5】:您确定 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 设置为您不会使用的字符(可能是|
),并将其用作变量中的参数分隔符:
X="a b|c"
IFS="|"
function f() echo $#; echo $1; echo $2;
f $X
【讨论】:
【参考方案6】:也可以结合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】:请不要将 eval 用于这样的事情。 set
将保持参数的完整性,echo
以外的命令将与它们很好地配合。请记住,您将丢失对任何当前位置参数的引用。
set -- "a b" "c"
echo "$@"
#a b c
echo $1
#a b
echo $2
#c
【讨论】:
【参考方案8】:这很麻烦,我建议解决这个问题,首先不要连接“a b”和“c”。
【讨论】:
以上是关于Linux/Bash:如何取消引用?的主要内容,如果未能解决你的问题,请参考以下文章