我以守护进程身份运行的 ruby 进程的 PID 文件获取了错误的 PID。运行似乎/etc/init.d/sinatra start
会创建两个进程 -sh
和ruby
,并且 PID 文件中最终显示的 PID 是进程的 PID sh
。这意味着当我运行/etc/init.d/sinatra stop
或时/etc/init.d/sinatra restart
,它会终止 sh 并使 ruby 进程仍在运行。
我想知道 a) 为什么我的脚本启动两个进程 - sh 和 ruby,而不仅仅是 ruby,以及 b) 我如何修复它以仅启动 ruby?
设置细节:
我在 ubuntu 服务器上设置了一个小型 Sinatra 服务器,作为守护进程运行。它设置为在服务器启动时自动运行一个名为 的脚本,sinatra
该/etc/init.d
脚本启动控制脚本control.rb
,然后运行 ruby 守护进程命令来启动服务器。该脚本在“sinatrauser”帐户下运行,该帐户具有脚本所需目录的权限。
/etc/init.d/sinatra 的内容
#!/bin/bash
# sinatra Startup script for Sinatra server.
sudo -u sinatrauser ruby /var/www/sinatra/control.rb $1
RETVAL=$?
exit $RETVAL
要安装此脚本,我只需将其复制到/etc/init.d/
并运行
sudo update-rc.d sinatra defaults
/var/www/sinatra/control.rb 的内容
require 'rubygems'
require 'daemons'
pwd = Dir.pwd
Daemons.run_proc('sinatraserver.rb', {:dir_mode => :normal, :dir => "/opt/pids/sinatra"}) do
Dir.chdir(pwd)
exec 'ruby /var/www/sinatra/sintraserver.rb >> /var/log/sinatra/sinatraOutput.log 2>&1'
end
ps -A 的输出部分
6967 ? 00:00:00 apache2
10181 ? 00:00:00 sh <--- PID file gets this PID
10182 ? 00:00:02 ruby <--- Actual ruby process running Sinatra
12172 ? 00:00:00 sshd
PID 文件在中创建/opt/pids/sinatra/sinatraserver.rb.pid
,并且始终包含 sh 实例的 PID,该 PID 始终比 ruby 进程的 PID 小一
编辑:我尝试了 micke 的解决方案,但它对我所看到的行为没有影响。
这是 的输出。无论我在 /etc/init.d 中的服务启动脚本中使用还是 ,ps -A f
此输出看起来都相同。sudo -u sinatrauser ...
su sinatrauser -c ...
1146 ? S 0:00 sh -c ruby /var/www/sinatra/sinatraserver.rb >> /var/log/sinatra/sinatraOutput.log 2>&1
1147 ? S 0:00 \_ ruby /var/www/sinatra/sinatraserver.rb
答案1
您使用的 exec 形式是造成这种情况的原因。如果将命令与参数分开,它将避免创建 shell。请参阅此 github 问题,了解修复类似问题的人:https://github.com/sunspot/sunspot/pull/221。
答案2
第一个进程是启动 ruby 的 sudo。使用 检查ps -A f
。更改 sudo 行以运行命令。
su sinatrauser -c "ruby /var/www/sinatra/control.rb $1"
编辑:我认为 su 在脚本中看起来更整洁,如下所示:
su - someuser <<CHBACK
ls $HOME // do stuff
echo "do more stuff as $USER"
CHBACK
echo "Now I'm $USER again"