在字符串中嵌入命令(Embedding commands in strings)

2019-10-21 08:43发布

考虑以下:

#!/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

如果$becho "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空间 。

Answer 1:

是啊, 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


Answer 2:

你必须牢记与命令替换的一件事是,每个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"打印所包含引号内文字 ,外壳去掉文字引号的字符串。

遗憾的最初的混乱。



文章来源: Embedding commands in strings