我有一个运行Flask的应用程序,并使用Compass作为css预处理器。这意味着我需要启动python服务器和指南针进行开发。我做了我认为是一个聪明的Rakefile,从一个命令启动所有内容,并且只在一个终端窗口中运行。
一切正常,但问题是当我试图阻止一切(使用cmd + c
)时,它只会杀死指南针任务并且Flask服务器继续运行。如何确保每项任务都停止?或者是否可以在没有此问题的情况下同时启动多个任务?
这是我的rakefile,非常简单:
# start compass
task :compass do
system "compass watch"
end
# start the flask server
task :python do
system "./server.py"
end
# open the browser once everything is ready
task :open do
`open "http://127.0.0.1:5000"`
end
# the command I run: `$ rake server`
multitask :server => ['compass', 'python', 'open']
修改
为了记录,我使用的是Makefile,一切都很完美。但是我改变了我的工作流程的一部分并开始使用Rakefile,所以我为了简单而将Rake文件全部删除并删除了Makefile。
答案 0 :(得分:1)
这是因为system
为您的命令创建了新进程。为了确保它们与你的红宝石过程一起被杀死,你需要自己杀死它们。为此,您需要了解system
未提供的流程ID,但spawn
会这样做。然后你可以等到它们退出,或者当你点击^ C时杀死子进程。
一个例子:
pids = []
task :foo do
pids << spawn("sleep 3; echo foo")
end
task :bar do
pids << spawn("sleep 3; echo bar")
end
desc "run"
multitask :run => [:foo, :bar] do
begin
puts "run"
pids.each { |pid| Process.waitpid(pid) }
rescue
pids.each { |pid| Process.kill("TERM", pid) }
exit
end
end
如果对此执行rake run
,命令将被执行,但是当您中止时,任务将被发送TERM信号。还有一个异常使它达到顶级水平,但我猜想一个Rake文件并不意味着要发布并不重要。等待过程是必要的,否则ruby过程将在其他过程和pid丢失之前完成(或者必须从ps
挖出来。)