考虑以下:
#!/bin/tcsh
set thing = 'marker:echo "quoted argument"'
set a = `echo "$thing" | sed 's/\([^:]*\):\(.*\)/\1/'`
set b = `echo "$thing" | sed 's/\([^:]*\):\(.*\)/\2/'`
echo $a
echo $b
$b
echo "quoted argument"
这使
marker
echo "quoted argument"
"quoted argument"
quoted argument
如果$b
是echo "quoted argument"
,为什么评估$b
给来自不同的结果echo "quoted argument"
?
因为我知道tcsh
是可怕的(但它是我所使用的工作),这里是猛砸了同样的问题:
thing='marker:echo "quoted argument"'
a=`echo "$thing" | sed 's/\(.*\):\([^:]*\)/\1/'`
b=`echo "$thing" | sed 's/\(.*\):\([^:]*\)/\2/'`
echo $a
echo $b
$b
echo "quoted argument"
输出是一样的。 需要注意的是,被我击这样做,我肯定会用的地图。 我没有这样的奢侈:)
。 该解决方案必须在工作tcsh
。
所需的输出
我想$b
表现得就好像我对自己输入的命令,我看到它:
marker
echo "quoted argument"
quoted argument
quoted argument
这是一个后续问题要访问数组元素在TCSH空间 。
是啊, eval
是“解决方案”在这里(以及解决的办法是不是有命令在首位的字符串看到http://mywiki.wooledge.org/BashFAQ/050更多)。
你看到的报价,当你运行的原因$b
是因为shell命令的计算顺序的。 使外壳程序的最后一步,所有其他扩展后,是远程引号(但它不会删除造成的任何扩展的引号)。
所以,当你有b='echo "quoted arguments"'
和运行$b
作为命令行会发生什么是变量扩展等你拿echo "quoted arguments"
,然后是运行原样。
$ c ()
{
printf 'argc: %s\n' "$#";
printf 'argv: %s\n' "$@"
}
$ b='echo "quoted arguments"'
$ c "quoted arguments"
argc: 1
argv: quoted arguments
$ c $b
argc: 3
argv: echo
argv: "quoted
argv: arguments"
$ c "$b"
argc: 1
argv: echo "quoted arguments"
$ eval c $b
argc: 2
argv: echo
argv: quoted arguments
$ eval c "$b"
argc: 2
argv: echo
argv: quoted arguments
你必须牢记与命令替换的一件事是,每个pipe
和每个command
你串起来自己的子shell中执行。 每次出现这种情况,外壳工艺您提供的命令或字符串时间:
如果$ b的回声报“援引论据”,为什么评估$ B给来自回声不同的结果“引述的说法”?
set thing = 'marker:echo "quoted argument"'
set b = `echo "$thing" | sed 's/\([^:]*\):\(.*\)/\2/'`
echo $b
echo "quoted argument"
在的情况下, b
,要指定从返回sed
,正是因为它返回到b
包括引号 。 他们成为一部分b
。 所以echo $b
相当于echo '"quoted argument"'
然而,你的echo "quoted argument"
打印所包含引号内的文字 ,外壳去掉文字引号的字符串。
遗憾的最初的混乱。