【问题标题】:Ruby system() doesn't accept UTF-8?Ruby system() 不接受 UTF-8?
【发布时间】:2012-07-30 21:18:35
【问题描述】:

我在 Windows 中使用 Ruby 1.9.3 并尝试执行一个操作,即我将文件名写入每行一个文件(我们将其称为文件列表),然后读取此文件列表,并调用 system() 到运行另一个程序,我将从文件列表中传递一个文件名。我用 system() 调用的那个程序将采用我传递给它的文件名并将其转换为二进制格式以在专有系统中使用。

在调用 system() 之前一切正常。我有一个 UTF-8 文件列表,从文件列表中读取文件名给了我正确的结果。但是当我运行时

system("c:\foo.exe -arg #{bar}")

传递的参数“bar”不是 UTF-8 格式。如果我使用日语、中文或任何文件名手动运行程序,它可以正常工作并正确编码文件,但如果我使用 system() 执行它就不会。我知道 bar 中的变量存储正确,因为我在其他地方使用它没有问题。

我也试过了:

system("c:\foo.exe -arg #{bar.encoding("UTF-8")}")
system("c:\foo.exe -arg #{bar.force_encoding("UTF-8")}")

两者都不起作用。我只能假设这里的问题是将 unicode 传递给系统。

其他人能否确认系统实际上是否支持此功能?

这里是代码块:

  $fname.each do |file|
    flist.write("#{file}\n")  # This is written properly in UTF-8
    system("ia.exe -r \"#{file}\" -q xbfadd") # The file being passed here is not encoding right!
  end

【问题讨论】:

  • 这似乎是一个长期存在的问题,在 Ruby 方面与 Windows 的糟糕集成。显然直到最近它仍然在很多事情上使用 ANSI API,system 可能被忽略了。

标签: ruby unicode utf-8


【解决方案1】:

我认为 bobince 的答案是正确的,对我有用的解决方案是:

system("c:\foo.exe -arg #{bar.encoding("ISO-8859-1")}")

【讨论】:

    【解决方案2】:

    我赞成 bobince 的回答;我相信它是正确的。

    我唯一要补充的是一个额外的解决方法,这是一个 Windows 问题,是将命令行写入批处理文件,然后使用 system() 调用批处理文件。

    我在运行 Calibre 的 ebook-convert 命令行工具时使用这种方法成功解决了这个问题,该工具的标题中包含 UTF-8/非英语字符。

    【讨论】:

      【解决方案3】:

      Ruby 的 system() 函数与大多数脚本语言中的函数一样,是 C 标准库 system() 调用的外层。 MS C 运行时对所有面向字节的 C 标准库函数使用 Win32 ANSI API。

      ANSI API 使用 Windows 系统区域设置(又名“ANSI 代码页”)在面向字节的字符串和用于文件名和 shell 命令的 Windows 原生 UTF16LE 字符串之间进行映射。不幸的是,无法将系统语言环境设置为 UTF-8;您可以在特定控制台上将代码页设置为 65001(Windows 相当于 UTF-8),但 MS CRT 在处理代码页 65001 时存在长期存在的错误,这会导致许多应用程序失败。

      所以使用标准的跨平台、面向字节的 C 接口意味着你不能支持 Unicode 文件名或 shell 命令,这是相当可悲的。一些脚本语言通过显式调用 Win32 'W' (Unicode) API 而不是 C stdlib 接口增加了对 Unicode 文件名的支持。 Ruby 1.9.x 在这方面正在取得进展,但system() 还没有被关注。

      您可以通过calling the Win32 API yourself 修复它,例如CreateProcessW,但它不是特别漂亮。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多