如何在此处文档中打印“ $”


43

如何在bash的here-doc中回显“ $”?

例如,我想在远程服务器上有一个包含内容的文件,例如$ABC=home_dir

$ ssh hostname sudo -s <<EOF
echo "$ABC=home_dir" > file
EOF

但这将被视为变量。如何打印文字$


2
您可以使用单引号
Rahul Patil

2
这是很多间接的过程。您确定不能在本地主机上创建该文件scp吗?
l0b0

Answers:


65

如果您想编写一个here-doc,并且不希望扩展任何doc或解释任何特殊字符,则可以用单引号将标签引号,如下所示:

$ cat >file <<'EOF'
echo "$ABC=home_dir"
EOF

但是,您的示例中所描述的情况要复杂得多,因为您实际上是通过ssh将这些内容发送到由sudo运行的远程系统,而sudo也是在调用shell(以便shell扩展内容)以及)。您将需要更多级别的引用才能正确执行此操作,但即使这样仍然无法正常工作,因为sudo需要一个终端(因此它可以要求输入密码),并且您已从stdin重定向。即使使用ssh -t也无济于事。

我也同意约翰。尚不清楚这真的是您想要的吗?请注意,将值赋给shell变量引用是不合法的,因此,如果您要创建的该文件应该是shell脚本,则将无法按照您的描述进行操作。也许如果您稍微备份一下并描述您真正想要做的事情,我们可以提供更多帮助。


这是最好的答案,因为它可以满足很长的HERE文档。(主要是)防止白痴。
菲利佩·阿尔瓦雷斯

23

逃脱 $

$ ssh hostname sudo -s <<EOF
echo "\$ABC=home_dir" > file
EOF

我不知道您的用例是什么,但是通常您想要home_dir=$ABC而不是$ABC=home_dir


2
该解决方案将起作用,但是OP想要的是真的吗?它似乎生成了一个shell脚本,当执行该脚本时,它将在“文件”中存储一个字符串,该字符串将对作业的左侧取消引用ABC,并可能最终存储=home_dir到文件中?当然,我不知道用例是什么...
Johan

2
这将导致文字$被发送到远程外壳程序,但是外壳程序将$ABC在向字符串回显之前扩展file。要将文字写入$文件,您需要另一个(转义的)反斜杠:echo "\\\$ABC=home_dir",以便远程外壳程序接收echo "\$ABC=home_dir"
13年

9

最便宜的转义方法是

$ ssh hostname sudo -s << \EOF
echo "$ABC=home_dir" > file
EOF

4

通过将字符串发送到cat远程端的进程,可以节省引用级别:

echo 'echo $ABC=home_dir' | ssh hostname sudo -s "cat > file"

单引号$在本地端保护,而字符串在另一壳上永远不会被外壳看到,因为它是由cat(via sudo)直接读取的,而不是作为另一个shell命令的参数。

使用您的代码,您将需要额外的转义层来保护$

$ ssh hostname sudo -s <<EOF
echo "\\\$ABC=home_dir" > file
EOF

您需要将文字发送\$到远程主机,以便远程外壳程序将文字写入$文件。您还可以通过引用here-doc标记来简化此操作:

$ ssh hostname sudo -s <<\EOF
echo "\$ABC=home_dir" > file
EOF
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.