Для ruby / webrick мне нужно, чтобы Windows распознавала нотацию shebang (#!)
Вопрос
(Потерпите меня, я обещаю, это дойдет до shebang и Windows.)
У меня есть примерно самый простой из собранных веб-серверов:
require 'webrick'
include WEBrick
s = HTTPServer.new(:Port=>2000, :DocumentRoot=>Dir::pwd)
s.start
Проще и быть не может.Этот базовый сервер принимает http-соединения (firefox, internet exploder, wget, TELENT) и обрабатывает их соответствующим образом, пока я просто извлекаю статические документы.Однако, если я установлю для одного из файлов в каталоге расширение .cgi, я получу обратно 500 и следующее на терминале сервера:
ERROR CGIHandler: c:/rubyCGI/test.cgi:
C:/...[snip]...webrick/httpservlet/cgi_runner.rb:45: in 'exec': Exec format error - ...[snip]...
Я сделал несколько вещей в командной строке, чтобы имитировать то, что происходит в строке 45 cgi_runner.rb
c:\>ruby
exec "c:/rubyCGI/test.cgi"
^Z
(same error erupts)
c:\>ruby
exec "ruby c:/rubyCGI/test.cgi"
^Z
Content-type: text/html
Mares eat oats and does eat oats and I'll be home for Christmas.
Очевидно, что WEBrick не был разрешен для размещения в Windows.Ваши обычные головные боли от корпоративной паранойи мешают мне модифицировать webrick, так что могу ли я получить обозначение shebang в c:/rubyCGI/test.cgi, распознанное ОС (Windows), чтобы мне не приходилось каждый раз явно указывать, какой интерпретатор использовать? Я мог бы назначить все файлы .cgi связанными с ruby, но в долгосрочной перспективе это было бы ограничением.
Обновить:После публикации этого мне пришло в голову, что, возможно, вообще невозможно запустить веб-сервер cgi из ruby;ruby не имеет поддержки разветвления.Не имея возможности разветвлять процесс, cgi-сервер должен был бы выполнять каждый cgi-скрипт по одному, игнорируя все параллельные запросы при выполнении первого.Хотя это может быть приемлемо для некоторых, это не сработало бы для моего приложения.Тем не менее, мне все равно было бы очень интересно получить ответ на мой первоначальный вопрос — о том, как заставить shebang работать под Windows.
Решение
Я думаю, что вы хотите связать расширение файла с Ruby.Я не думаю, что возможно заставить нотацию !# работать в Windows, но можно заставить Windows автоматически запускать скрипт с определенным интерпретатором (как в вашем втором примере).Хорошее пошаговое обсуждение того, что вы хотели бы сделать, это вот. Вы конкретно хотите, чтобы раздел был озаглавлен:"Создать ассоциации файлов для несвязанных типов файлов".Я думаю, это позволит достичь того, что вы пытаетесь сделать.
Другие советы
Универсальное решение, которое работает как для Ruby 1.8.6.pxxx, так и для 1.9.1.p0 в Windows Заключается в следующем:
Отредактируйте файл:c: uby\lib uby\1.9.1\webrick\httpservlet\cgi_runner.rb
Добавьте следующие строки в верхней части файла:
if "1.9.1" == RUBY_VERSION require 'rbconfig' #constants telling where Ruby runs from end
Теперь найдите последнюю строку, где написано:exec ENV["SCRIPT_FILENAME"] Прокомментируйте эту строку и добавьте следующий код:
# --- from here --- if "1.9.1" == RUBY_VERSION #use RbConfig Ruby = File::join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name']) Ruby << RbConfig::CONFIG['EXEEXT'] else # use ::Config Ruby = File::join(::Config::CONFIG['bindir'], ::Config::CONFIG['ruby_install_name']) Ruby << ::Config::CONFIG['EXEEXT'] end if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM exec "#{Ruby}", ENV["SCRIPT_FILENAME"] else exec ENV["SCRIPT_FILENAME"] end # --- to here ---
Сохраните файл и перезапустите сервер webrick.
Объяснение:Этот код просто создает переменную 'Ruby' с полным путем к "ruby.exe", и (если вы работаете в Windows) он передает дополнительный параметр "c: uby\bin uby.exe" , к методу Kernel.exec(), чтобы ваш скрипт мог быть выполнен.
На самом деле не для того, чтобы спорить...но зачем беспокоиться о webrick, когда mongrel намного быстрее и с нативной компиляцией в Windows?И, конечно, это означает, что никакой шумихи не нужно.
На самом деле, можно заставить Windows распознавать обозначения shebang в файлах сценариев.Это может быть сделано с помощью относительно короткого скрипта, скажем, на Ruby или AutoIt.Требуется только довольно простой анализатор для первой строки файла сценария, а также некоторые манипуляции с файлом.Я делал это пару раз, когда либо требовалась кросс-совместимость файлов сценариев, либо когда расширений файлов Windows было недостаточно.