Command Error: /usr/bin/env: 'ruby2.6': No such file or directory

Command Error: /usr/bin/env: 'ruby2.6': No such file or directory

我 运行 在我们的生产服务器上遇到问题,我们有一个 Rails 应用程序使用 gem wicked_pdf 生成 PDF,它抛出以下错误:

Failed to execute:
["/var/www/myapp/vendor/cache/ruby/2.6.0/bin/wkhtmltopdf", "file:////tmp/wicked_pdf20201004-5058-g9f64a.html", "/tmp/wicked_pdf_generated_file20201004-5058-1gjfrw5.pdf"]
Error: PDF could not be generated!
 Command Error: /usr/bin/env: 'ruby2.6': No such file or directory

现在奇怪的是,这在 rake 任务中运行良好(rake 任务使用 sudo 执行)

当然 ruby 解决得很好:

$ which ruby
/usr/bin/ruby

$ which ruby2.6
/usr/bin/ruby2.6

$ ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux-gnu]

$ echo $PATH
/home/julien/bin:/home/julien/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Rails 应用与 www-data 用户一起运行。 Ubuntu 16.04.5 LTS。

我的猜测是 bash 应用程序用来执行二进制文件的 $PATH 缺少某些东西,或者我可能在某处需要一个符号 link 但我不知道,有什么想法吗?

我怎样才能调试它以了解问题出在哪里? 我如何检查并可能修改 Rails 加载的 shell 路径?

更新

Rails 应用使用 Nginx + Passenger 运行。

ENV['PATH'] 输出如下:

/var/www/myapp/vendor/cache/ruby/2.6.0/bin 

这是生成 PDF 的代码的相关部分:

#generate the PDF
  pdf = WickedPdf.new.pdf_from_string(
    ActionController::Base.new.render_to_string(
      template: 'templates/_doc',
      locals: {
        url: self.url,
        signature: sig,
        name: full_name,
        title: "some title"
      }
    )
  )

  #save the file
  save_path = Rails.root.join(PATH_TO_STORE_FILE, "some-filename-#{self.clean_url}.pdf")
  File.open(save_path, 'wb') do |file|
    file << pdf
  end

无需弄清楚在哪里编辑 PATH,解决问题的最简单方法是:

cd /var/www/myapp/vendor/cache/ruby/2.6.0/bin
ln -s /usr/bin/ruby2.6 .

这样您的供应商 bin 文件夹中就会有一个指向 ruby2.6 的 link,并且由于该文件夹位于您的 Web 服务器的路径中,它应该可以解决您的问题。

WickedPdf 在某些情况下会尝试通过调用 which wkhtmltopdf 来找出 wkhtmltopdf 的位置。在这里,它选择了一个调用 Ruby 2.6 的二进制存根 (binstub),但是调用它的进程在其 PATH 中没有它。

您可以明确指定 wkhtmltopdf 二进制文件的路径,如下所示:

WickedPdf.config = {
  exe_path: '/usr/local/bin/wkhtmltopdf'
}

理想情况下,这应该是实际二进制文件的直接路径,而不是 binstub,但是一些提供 wkhtmltopdf 作为二进制文件的 gem,使用 binstub 根据执行它的平台切换二进制文件。

如果使用其中之一,像这样的东西应该可以工作:

WickedPdf.config = {
  exe_path: "#{ENV['GEM_HOME']}/gems/wkhtmltopdf-binary-#{Gem.loaded_specs['wkhtmltopdf-binary'].version}/bin/wkhtmltopdf_linux_amd64"
}