嵌套引用噩梦:从远程主机发送电子邮件

嵌套引用噩梦:从远程主机发送电子邮件

我需要(从我的终端)从我通过 ssh 访问的远程主机发送一封带有附件的电子邮件。我已经知道要远程执行某些操作,我会使用

ssh -p myport [email protected] "doSomething"

我也知道要发送带有附件的电子邮件,我需要

echo "Mail content" | mailx -s "Mail title" -a attachment.txt -S from="myname@gmail" destname@gmail

因此,两者的简单组合就是简单地doSomething用第二行的全部内容替换第一行。当然,这是行不通的,因为有可怕的嵌套双引号。如何完成这项工作(如果可能的话,干净利落地)?任何帮助表示赞赏。

答案1

对于简单的情况,您可以使用单引号来保护本地 shell 中的命令,或者将双引号转义为\".

echo "Mail content" | ssh -p myport [email protected] 'mailx -s "Mail title" -a attachment.txt -S from="myname@gmail" destname@gmail'
# or
echo "Mail content" | ssh -p myport [email protected] "mailx -s \"Mail title\" -a attachment.txt -S from=\"myname@gmail\" destname@gmail"

对于更复杂的事情,最简单的可能是使用定界符来设置变量:

read -r -d '' mailcmd <<'CMD'
echo "quotin'" 'this would be a "nightmare" indeed.' | mailx -s "Anthony's Email" -a attachment.txt -S from="myname@gmail" destname@gmail
CMD
ssh -p myport [email protected] "$mailcmd"

至少在 bash 中,您可以要求 shell 为您引用一个变量,这在您需要做更烦人的事情(例如,链接两个ssh调用)时可能会有所帮助:

$ printf '%q\n' "$mailcmd"
echo\ \"quotin\'\"\ \'this\ would\ be\ a\ \"nightmare\"\ indeed.\'\ \|\ mailx\ -s\ \"Anthony\'s\ Email\"\ -a\ attachment.txt\ -S\ from=\"myname@gmail\"\ destname@gmail

如您所见,它的自动引用并未针对最少的反斜杠进行优化。

包括局部变量

如果需要在命令中使用变量,ssh 提供了一种有效的特殊情况:ssh 可以传递由SendEnv选项(客户端)和AcceptEnv选项(服务器)指定的环境变量。如果您传递环境变量,远程端 shell 可以正常扩展它们(如果您在此处文档中有“$varname”,则远程端 shell 也会扩展它们)。

除此之外,最简单的方法是省略定界文档中的引号,这将使扩展发生(尽管这意味着您必须$在您不想要的地方转义):

$ var1="hello world"
$ read -r -d '' mailcmd <<CMD
echo "$var1" "\$var1"
CMD
$ echo "$mailcmd"
echo "hello world" "$var1"

请注意我如何使用;CMD代替'CMD'像这样引用结束标记会关闭扩展。因此,通过不引用它,我们得到了扩展。并按预期"$var1"扩展hello world,但通过在其前面放置反斜杠可以避免扩展。请注意,所有扩展均已启用,包括反引号和$(…)扩展。另请注意,var1 只是被替换为; shell 不会在那里进行任何转义,因此如果 var1 包含双引号(等),则该方法不起作用。这是您可以使用 %q 的地方:

$ var1='hello "world"'
$ read -r -d '' mailcmd <<CMD
echo $(printf '%q' "$var1") "\$var1"
CMD
$ echo "$mailcmd"
echo hello\ \"world\" "$var1"

一句警告:如果您传递的数据可能会受到攻击者的影响,那么您必须非常小心。转义中的任何轻微错误(或者所有涉及的 shell 之间需要转义的内容的不同定义)都可能成为任意代码执行缺陷。构建更强大的数据传递系统通常比确保所有必需的转义都存在/正确更容易。很多的安全漏洞一直在逃避失败。

相关内容