如何*不*扩展"〜"在tcsh backtick / eval包装器中?

时间:2016-03-01 02:11:35

标签: eval alias wrapper tcsh

我对"为什么tcsh是邪恶"不感兴趣?回答,这个问题需要tcsh才能使用。如果这是tcsh中的错误,请告诉我。

我一般都非常擅长引用输出,但我已经被我必须处理的用例所困扰。以下是简化案例:

我有一个可执行文件,我评估输出。有时它需要打印输出(到标准输出),所以我尝试使用echo(builtin),/ bin / echo和/ bin / printf。

作为一个简单的例子,假设我的可执行文件被称为" simpleWrap"它输出

echo "hello world"

所以我跑(最终使用别名,但这里不相关):

eval `simpleWrap`

我得到了,正如所料:

hello world

但这就是问题所在。有时我需要在输出中使用波浪号。所以,让我们尝试一些例子。我们将tildes放在simpleWrap输出中(这不是脚本的内容,而是输出):

echo "These are tildes:  ~ and \~ and \\~"

令人惊讶的是,当我现在评估simpleWrap的输出时,我得到:

These are tildes: /home/dave and \~ and \~

将〜扩展到我的主目录,或者\保护它,但我无法摆脱反斜杠。

我怎样才能打印一个'〜'在带有反引号的eval的输出中?

我认为反击是强迫〜扩张,但他们并没有以一致的方式做到这一点。例如,如果我跳过反引号并执行:

eval echo "These are tildes:  ~ and \~ and \\~"

然后我得到一致的预期输出:

These are tildes: /home/dave and ~ and \~

反引号中的替换是否有问题,或者我错过了正确的引用可能性? (我也尝试用单引号和双引号包装无效)

1 个答案:

答案 0 :(得分:2)

差异来自命令shell替换发生,以及解析\的不同行为,当它在双引号内时,而不是双引号。

演示\

的行为
echo \~
=> ~
echo "\~"
=> \~
echo "\\~"
=> \~

场景1

eval `simpleWrap`

此处," simpleWrap"输出" raw"包括波浪的弦。然后将字符串未更改(无替换)传递给eval命令(因为这是反引号的工作原理),它基本上运行一个新的shell。所以新的shell看到了这个命令行:

echo "These are tildes:  ~ and \~ and \\~"

(请注意eval命令可以看到引号。

此命令的输出是您没有预料到的,即\~(表示A)和\\~(表示B)产生相同的输出。为什么呢?

首先,A和B都没有被替换,因为波形符替换仅在波形符是其单词中的第一个字符时发生,而不是这两种情况。

现在,对于A,由于\~不是已知的转义序列(例如,与\n不同),因此shell将其保留原样,生成\~

对于B,\\ 一个已知的转义序列,因此shell正确地将其解释为\,然后将其余的字符串附加到它,生成{{ 1}}再次。

场景2

\~

这里,只有一个命令行,其中包含代字号。首先,存在shell替换,它既不影响A也不影响B,但在此阶段,引号丢弃(它们用于将单词分组为单个参数,并且不传递给命令)。然后,eval echo "These are tildes: ~ and \~ and \\~" 运行(eval还没有运行),并将其作为输入传递:echo

请注意报价已下降。没有引号的命令输出是您所期望的(参见"演示"上面):

echo These are tildes:  ~ and \~ and \\~

如何使其有效?

删除引号!

echo These are tildes: /home/dave and \~ and \\~ => These are tildes: /home/dave and ~ and \~ 应该打印出来:

simpleWrap

而不是:

echo These are tildes:  ~ and \~ and \\~