Ubuntu 16.04中Upstart status命令及Kernel.capture替代方案咨询
1. Ubuntu 16.04 替代 Upstart status 命令的方案
Ubuntu 16.04 默认采用 systemd 作为初始化系统,完全替代了旧版的 Upstart。你需要把原有的 Upstart 服务管理命令切换为 systemd 的 systemctl 工具。
针对你检查 workers 服务是否运行的需求,最可靠的方式是使用 systemctl is-active 命令——它通过退出码直接返回服务状态,不需要依赖输出文本匹配:
- 返回码为 0 → 服务处于运行状态(active)
- 返回码非 0 → 服务未运行(inactive/failed)
在 Ruby 代码里,你可以直接用 system 方法判断执行结果(system 会在命令退出码为 0 时返回 true,否则返回 false):
if system('systemctl is-active --quiet workers.service') # workers 服务正在运行,执行你的业务逻辑 end
这里的 --quiet 参数会关闭命令的输出,只保留退出码,非常适合脚本里的状态判断场景。
如果你的 workers 服务还没迁移到 systemd,需要先创建对应的 service 配置文件,比如在 /etc/systemd/system/workers.service 中写入:
[Unit] Description=Workers Background Service After=network.target [Service] User=deploy WorkingDirectory=/var/www/your_app_root ExecStart=/bin/bash -c 'bundle exec sidekiq -C config/sidekiq.yml' Restart=always Environment=RAILS_ENV=production [Install] WantedBy=multi-user.target
然后执行以下命令完成服务的启用和启动:
sudo systemctl daemon-reload sudo systemctl enable workers.service sudo systemctl start workers.service
2. 替代已弃用的 Kernel.capture 的方案
Kernel.capture 在 Ruby 2.6 及以上版本被标记为弃用,官方推荐使用 Ruby 标准库中的 Open3 模块——它提供了更安全、灵活的命令执行和输出捕获能力。
场景1:仅需要判断命令是否执行成功(如检查服务状态)
这种情况用前面提到的 system 方法就足够了,代码简洁且直接返回布尔值,完全能替代原有的捕获输出再匹配的逻辑。
场景2:需要捕获命令的输出或错误信息
如果需要获取命令的标准输出/错误输出,可以用 Open3.capture3:
require 'open3' # 同时捕获标准输出、错误输出和执行状态 stdout, stderr, status = Open3.capture3('systemctl status workers.service') # 结合退出码和输出文本判断服务状态 if status.success? && stdout.include?('active (running)') # 执行你的业务逻辑 end
如果要避免 shell 注入风险(比如命令参数包含特殊字符),推荐用数组形式传递命令和参数:
stdout, stderr, status = Open3.capture3('systemctl', 'status', 'workers.service')
另外,Open3.capture2 仅捕获标准输出,Open3.capture4 会同时捕获输出并返回线程对象,你可以根据具体需求选择合适的方法。
内容的提问来源于stack exchange,提问作者qanknku

