Подтвердить что ты не робот

Поток консоли через HTTP (с Ruby)

Я пытаюсь выполнить некоторые команды удаленно, и SSH'ing на машине не является опцией. То, что я пытаюсь сделать, это настроить приложение Sinatra, которое запускает определенные команды и передает потоки через HTTP.

Пример действия выглядит следующим образом:

get "/log" do
  `tail -f some.log`
end

1 Насколько я читал, мне нужно использовать Unicorn (или Mongrel), потому что Thin не поддерживает потоковые данные 2 Мне кажется, мне нужно выполнить вывод команд через какой-то объект ручного ввода-вывода

Я почти знаю, как это сделать (1), но не знаю, как достичь (2).

4b9b3361

Ответ 1

Если вы находитесь на синхронном сервере (т.е. Mongrel, Unicorn, not Thin), вы можете просто вернуть объект IO:

require 'sinatra'

get '/log' do
  content_type :txt
  IO.popen('tail -f some.log')
end

Если это не работает (например, если вы используете Thin), вы можете использовать новый потоковый API:

require 'sinatra'

get '/log' do
  content_type :txt
  IO.popen('tail -f some.log') do |io|
    stream do |out|
      io.each { |s| out << s }
    end
  end
end

Вы также можете использовать bcat gem, который будет раскрашивать ваш вывод, если он содержит цветовые коды ANSI:

require 'sinatra'
require 'bcat'

get '/log' do
  command = %[tail -f some.log]
  bcat = Bcat.new(command, :command => true)
  bcat.to_app.call(env)
end

Примечание. Для бесконечно бегущего процесса вам придется самому позаботиться об убийстве процесса, если кто-то закроет соединение. При первом решении некоторые серверы могут позаботиться об этом для вас.