【问题标题】:Ruby script can't open SQLite3 file, but only when running as a DaemonRuby 脚本无法打开 SQLite3 文件,但只能在作为守护进程运行时打开
【发布时间】:2019-09-30 16:50:35
【问题描述】:

我正在运行一个脚本(在 AWS EC2 实例上运行),该脚本不断从 API 中提取州立法数据,并将其保存到 SQLite3 .db 文件中。当我尝试在后台将脚本作为守护进程运行时,该进程立即停止并出现以下错误。

stateleg.rb: process with pid 4666 started.
Traceback (most recent call last):
    11: from stateleg_daemon.rb:4:in `<main>'
    10: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons.rb:149:in `run'
     9: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons/cmdline.rb:121:in `catch_exceptions'
     8: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons.rb:150:in `block in run'
     7: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons/controller.rb:59:in `run'
     6: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons/application.rb:307:in `start'
     5: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons/application.rb:228:in `start_load'
     4: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons/application.rb:228:in `load'
     3: from /home/ubuntu/stateleg.rb:8:in `<top (required)>'
     2: from /home/ubuntu/stateleg.rb:8:in `new'
     1: from /usr/local/rvm/gems/ruby-2.5.1/gems/sqlite3-1.4.1/lib/sqlite3/database.rb:89:in `initialize'
/usr/local/rvm/gems/ruby-2.5.1/gems/sqlite3-1.4.1/lib/sqlite3/database.rb:89:in `open_v2': unable to open database file (SQLite3::CantOpenException)

当我尝试在前台运行脚本时,脚本运行完美,必要的信息被写入 .db 文件。

如何让这个守护进程打开数据库文件? SQLite3 和 Ruby 守护进程在某种程度上不兼容吗?任何信息都会非常有帮助。

这是整个守护程序脚本。

require 'daemons'

Daemons.run('stateleg.rb')

【问题讨论】:

  • SQLite 文件的权限是什么?它是否属于运行守护程序的同一用户?
  • 如何打开文件?您是否提供了绝对路径
  • @muistooshort 我不知道如何检查权限,但我创建了脚本和 SQLite 文件。
  • @tadman 这是 stateleg.rb 中的相对路径 ``` db = SQLite3::Database.new('stateleg.db') ``` 但是,当我在前台,访问stateleg.db没有问题
  • 尝试使用绝对路径,你永远不知道守护进程的当前目录是什么。您可以使用ls -l 作为快速检查所有者和权限的方法。

标签: ruby sqlite daemon sqlite3-ruby daemons


【解决方案1】:

当某些东西被“守护”时,它通常运行在与您期望的不同的工作目录中。对于在启动时启动的服务尤其如此,例如通过systemdcron

为了解决这个问题,您需要指定要使用的文件的完整路径。这些被称为绝对路径,因为它们不受当前工作目录的影响。 /a/b/c 是绝对路径,它以/ 开头,但b/c 是相对路径。如果您在 /a 中,它是等效的,但它不会在该范围之外工作。

如果您知道该文件相对于您的脚本的位置,您通常可以这样做:

Daemons.run(File.expand_path('stateleg.rb', __dir__))

其中__dir__ 是存储当前执行脚本文件的目录。

【讨论】:

    猜你喜欢
    • 2016-01-01
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    相关资源
    最近更新 更多