Ruby 我如何确保一个进程正在运行,即使它自杀了?(然后需要重新启动)

Ruby 我如何确保一个进程正在运行,即使它自杀了?(然后需要重新启动),ruby,linux,process,cron,boot,Ruby,Linux,Process,Cron,Boot,我正在使用linux。我希望每次启动计算机时都能运行一个进程(irc bot)。但是我遇到了一个问题:网络很糟糕,经常断开连接,所以我需要每天手动重启机器人几次。如何实现自动化 其他信息: bot创建一个名为bot.pid的pid文件 机器人会重新连接自身,但只会连接几次。网络太糟糕了,所以机器人有时会自杀,因为它没有得到响应 我目前所做的(也称为我的方法;)) 我有一个cron作业,每5分钟执行一次startbot.rb。(脚本本身与bot位于同一目录中) 剧本: #!/usr/bin/rub

我正在使用linux。我希望每次启动计算机时都能运行一个进程(irc bot)。但是我遇到了一个问题:网络很糟糕,经常断开连接,所以我需要每天手动重启机器人几次。如何实现自动化

其他信息: bot创建一个名为bot.pid的pid文件 机器人会重新连接自身,但只会连接几次。网络太糟糕了,所以机器人有时会自杀,因为它没有得到响应

我目前所做的(也称为我的方法;)) 我有一个cron作业,每5分钟执行一次
startbot.rb
。(脚本本身与bot位于同一目录中)

剧本:

#!/usr/bin/ruby
require 'fileutils'

if File.exists?(File.expand_path('tmp/bot.pid'))
  @pid = File.read(File.expand_path('tmp/bot.pid')).chomp!.to_i
  begin
    raise "ouch" if Process.kill(0, @pid) != 1
  rescue
    puts "Removing abandoned pid file"
    FileUtils.rm(File.expand_path('tmp/bot.pid'))
    puts "Starting the bot!"
    Kernel.exec(File.expand_path('./bot.rb'))
  else
    puts "Bot up and running!"
  end
else
  puts "Starting the bot!"
  Kernel.exec(File.expand_path('./bot.rb'))
end
它的作用是: 它检查pid文件是否存在,如果是真的,它会检查
kill-s0bot\u pid==1(如果BOT正在运行),如果两个检查之一失败/不正确,则启动BOT


我的方法似乎很肮脏,那么我该如何做得更好呢?

有一个名为daemontools的工具,它是用来监督和管理UNIX服务的


从你的生活中,你可以学习和使用它

重新启动应用程序是一个糟糕的解决方法,而不是解决方案

我建议您查看bot的文档,寻找一个选项来配置它退出多少次错误重试后,或者如何完全禁用此功能。如果bot是开源的,您还可以查看其源代码并修改重试代码。设法找到一个干净的解决办法

编辑:现在,如果您的系统使用systemd而不是init,请为您的bot创建一个服务文件/etc/systemd/system/bot.service,如下所示:

[Unit]
Description=bot service
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=10
ExecStart=/usr/bin/ruby /path/to/bot.rb

[Install]
WantedBy=multi-user.target
这将在10秒后重新启动bot。也可以考虑使用<代码>用户=/COD>指令,因此如果不需要的话,它不在根权限下运行,也不使用StReD的用户实例。有关选项的更多信息,请参阅systemd。有关用户systemd服务,请参阅和

然后使用systemctl enable bot(重新启动后启动bot)和systemctl start bot启动bot

或者,我将创建一个在循环中运行bot的shell脚本。确保bot.rb不会进入后台:

#/bin/bash
for (( ; ; ))
do
     ./bot.rb
done
您可以使用
nohup./startscript.sh&

因此,如果您关闭控制台,它不会终止。

这是一个很好的答案,谢谢,但我认为我可以通过循环更轻松地归档相同的内容;)