1

当我的 ruby​​ 脚本失败时,我正在构建一种通过 mutt 向我发送电子邮件的方法。它看起来像这样:

begin
    UnknownFunction()
rescue
    subject = 'Error'
    to_array = ['email@email.com','email2@email.com']
    body = "An error occurred:\n#{$!}"
    %x[echo "#{body}" | mutt -s "#{subject}" #{to_array.join(",")}]
end

该命令引发以下错误:

sh: -c: line 1: unexpected EOF while looking for matching ``'
sh: -c: line 2: syntax error: unexpected end of file

我终于仔细看了一下,看到了$!在未定义的方法名称前包含一个反引号,后跟一个单引号:

undefined method `UnknownFunction' for main:Object

我深入研究了代码并验证了 method_missing 方法之前有一个反引号,之后有一个单引号。反引号应该是单引号还是反之亦然?如果不是,其背后的原因是什么?

raise NoMethodError, "undefined method `#{mid}' for #{self}", caller(1)
4

3 回答 3

3

它是纯文本/Unicode 前环境中开放单引号 (') 的替代品。请参阅:为什么纯文本技术文章经常将术语括在反引号和单引号中?

于 2014-07-14T19:09:56.240 回答
2

NoMethodError 的描述并不是代码,所以这里使用反引号纯粹是出于审美原因。如果要将任意字符串传递给 shell,请使用Shellwords.shellescape

于 2014-07-14T19:12:26.637 回答
1

反引号对于简单的命令很好,但是一旦你开始向子进程抛出数据,我认为使用更复杂的东西比通过echo. 我会使用IO.popen

IO.popen(
  "mutt -s '%s' %s" % [ subject, to_array.join(',') ],
  'w'
) do |mutt|
  mutt.puts body
end

这是未经测试的,但这是我要开始的。它更具可读性,因为它摆脱了插值变量的反引号丛林。它还避免了子 shell 试图通过解释变量或在发送给 mutt 的文本中寻找嵌入的反引号来提供帮助的潜在问题。

于 2014-07-14T19:57:31.340 回答