1

Ruby 安装中有一些批处理文件引用了这个Ruby exe ( $~dp0ruby.exe)。例如,gem.bat(注意最后一行)

@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
ECHO.This version of Ruby has not been built with support for Windows 95/98/Me.
GOTO :EOF
:WinNT
@"%~dp0ruby.exe" "%~dpn0" %*

但是,一些 gem 会得到一个引用系统Ruby ( )的批处理文件ruby.exe,无论PATH. 例如,bundle.bat

@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"ruby.exe" "C:/Ruby192/bin/bundle" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"ruby.exe" "%~dpn0" %*

我有一个用于 .NET 项目的隔离 Ruby 环境(开发人员或构建代理不太可能拥有系统 Ruby)。但是,许多 gem(bundler、rake 等)正试图在不存在的系统 Ruby 中执行。

C:\
  Ruby192\            <-- System Ruby, would be here
    bin\                  and this bin would be in the
      bundle.bat          PATH
      gem.bat
      ruby.exe

  <some-other-path>\  <-- An isolated environment, in
    Ruby\                 my problem, this is deployed 
      bin\                to a build agent
        bundle.bat
        gem.bat
        ruby.exe

是什么赋予了?这是 ruby​​gems创建批处理文件的方式的缺陷吗?

def windows_stub_script(bindir, bin_file_name)
  ruby = File.basename(Gem.ruby).chomp('"')
  return <<-TEXT
@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"#{ruby}" "%~dpn0" %*
TEXT
end

ruby.exe不引用你曾经使用过的gem install这个 gem的想法是什么?我只是做错了吗?我应该需要一个系统 Ruby,然后使用 Bundler 或其他东西来隔离它吗?

4

1 回答 1

3

我是 RubyInstaller 项目的维护者之一,该项目产生了您展示的第一个批处理文件。

编译 Ruby 时,我们将 Ruby 构建的生成的批处理文件替换为我们自己的batch_stub

这个存根被认为%~dp0是 Ruby 的可执行文件相对于这个批处理文件的位置,因为我们知道这些批处理文件将与可执行文件一起存在。

Gems 可以安装在任何地方,而不仅仅是在 Ruby 的树中(例如,使用 Bundler 或gem install --install-diror --bindir)。

在这些情况下, RubyGems 批处理文件不能%~dp0用来确定 Ruby,这就是为什么这些批处理文件存根 ruby.exe包含在其中的原因。

正如您所指出的,问题在于ruby.exe将从 中找到PATH,其中包含您的全局 Ruby 安装,而不是您正在处理的孤立的安装。

快速修复将在PATH此隔离 Ruby 的目录前添加:

SET PATH=C:\<some-other-path>\Ruby\bin;%PATH%

你可以把它放在一个批处理文件中,比如setenv.bat在执行 Ruby 之前调整环境(或作为启动脚本)。

另一种选择是使用类似gem-exefy 的东西,它将替换可执行存根的批处理文件,并将使用相对于它找到的 Ruby dll,因此将使用隔离版本而不是全局版本。

对于家庭作业,我不确定是否bundle exec会起作用,因为它将PATH用于查找要运行的可执行文件,因此无法详细告诉您。

希望这能解释为什么 RubyGems 生成的批处理文件与 RubyInstaller 生成的批处理文件不同。

于 2012-09-19T15:23:05.123 回答