Shell 带转义回勾和$

Shell 带转义回勾和$,shell,sed,sh,echo,Shell,Sed,Sh,Echo,test.sh COMMAND1="Build `date`" COMMAND2="echo $PATH" echo "Command1 is: $COMMAND1" echo "Command2 is: $COMMAND2" 输出 Command1 is: Build Wed Dec 26 21:09:43 UTC 2018 Command2 is: echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 在上面

test.sh

COMMAND1="Build `date`"
COMMAND2="echo $PATH"

echo "Command1 is: $COMMAND1"
echo "Command2 is: $COMMAND2"
输出

Command1 is: Build Wed Dec 26 21:09:43 UTC 2018
Command2 is: echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
在上面的shell脚本中,如何在不计算表达式的情况下进行回显,即我想要
Command1是:Build`date`

我知道我可以转义
`
$
字符,但在我的应用程序中,它们来自上游服务,并作为参数传递给shell脚本。甚至上游服务也无法逃避它们,因为在脚本的后面,我实际上需要执行这些命令


理想的方法是告诉echo只展开变量
$COMMAND1
,而不计算其中的任何内容。或者使用
sed
来转义所有出现的
`
$
,但我都无法实现。

表达式是在赋值时计算的

COMMAND1="Build `date`"
“…”代表命令替换(它被弃用为
$(…)
)。\“引号用于允许展开文本。因此,首先将此命令展开为:

COMMAND1='Build Wed Dec 26 21:09:43 UTC 2018'
然后赋值就发生了。你以后无法检索用来声明变量的命令。这些信息会丢失。如果你有一些上游信息,它需要将这些信息传递给你

如果希望
COMMAND1
包含字符串(字面意思)

您可以使用单引号:

COMMAND1='Build `date`'
您可以稍后使用
eval
或类似的组合来扩展变量,但是我建议只执行一个函数

COMMAND1() {
   Build $(date)
}

echo "COMMAND1 is declared as:"
declare -f COMMAND1
echo "COMMAND1 execution returns: $(COMMAND1)"
有用链接:


请注意,将命令存储在字符串变量中被认为是一种不好的做法——它天生就容易出错。请参阅,以了解如何以及为什么会出现错误,以及可用的替代方法。@CharlesDuffy感谢您的链接。
set-x
选项很有趣。我会尝试一下。哇,这很完美。因此,您建议使用单引号d然后
eval
工作得很好。我不理解你的第二个使用函数的建议。而且我在阿尔卑斯山,所以
declare
对我不起作用。除了
declare
,还有其他选择吗?在我接受你的答案之前,给我一些时间做更多的实验。谢谢。Busybox的shell是posix she的受限版本我发现docker上有
类型
,但不允许打印函数声明。对于declare builtin,您需要安装bash。如果使用
eval
,请准备好正确转义您的命令。也许更好的解决方案是使用subshell
sh-c“$命令“
也将双重解释参数,如果该命令不应影响当前环境,则会起作用。如果以后确实需要对
date
进行求值,我将重新构造代码,并定义一个函数,在您最终准备好日期时调用该函数。”。尽可能避免
eval
COMMAND1() {
   Build $(date)
}

echo "COMMAND1 is declared as:"
declare -f COMMAND1
echo "COMMAND1 execution returns: $(COMMAND1)"