46

2014 年 1 月 9 日更新:TL;DR 版本: 转到这篇文章的底部以获取让 Cygwin 能够调用非 Cygwin 程序的方法。

在花时间制作了一些碰巧很大的 bash 脚本之后,较新版本的 Cygwin 已经破坏了它们。这些脚本调用不与 Cygwin 链接的本机 Win32 应用程序,这显然不受 Cygwin 的官方支持。

这让我感到惊讶,因为多年来我一直认为 Cygwin 可以在一个更加混合的环境中使用,该环境结合了本地非 Cygwin Win32 应用程序和使用 Cygwin 兼容层的 POSIX 程序。但显然只有 POSIX 兼容层真正得到支持,如果本机 Win32 非 Cygwin 应用程序工作,那么这被认为是一个快乐的巧合。

我从 Cygwin 中运行的针对 .NET Framework 编译的程序遇到的不兼容问题中发现了这一点。这曾经工作得很好,但几个月前就坏了。具体来说,通过管道传输到任何其他 Win32 程序标准输入的 .NET 程序的标准输出通常会导致接收 Win32 程序获得过早的文件结束信号,因为几个月前 Cygwin 最近从字节管道切换到消息管道- 并且消息管道似乎与任何使用 Visual C++ 或 .NET Framework 的接收应用程序不兼容。这是因为 .NET 向标准输出发出空写入,仅在使用消息管道时才将其传递给接收应用程序。接收应用程序成功读取零字节,因此认为它是文件结尾。项目负责人不

从邮件列表中的多封电子邮件中引用项目负责人 Christopher Faylor 的话:

您所看到的可能是因为 Cygwin 在几次修订前被更改为使用消息类型管道。这不会改变。采用该更改是为了解决 Cygwin 程序的问题,而这些显然是我们的第一要务。

无论有多少人使用 Visual C++ 或 .NET,他们都不是我们的目标受众。对于不想使用 UNIX 工具但它们不是我们主要关注点的人来说,这很好。为想要使用非 Cygwin 东西的人解决问题并不是我认为的高优先级。

来自 pipe.cc:请注意,管道的写入端以 PIPE_TYPE_MESSAGE 的形式打开。这似乎更接近于模拟 Linux 管道行为,并且对于 pty 处理肯定是必需的,因为 fhandler_pty_master 以块的形式写入管道,在指定 CANON 模式时由换行符终止。

上面的评论在这里显示了“和”的关系。消息类型管道更接近地模仿 Linux (UNIX) 管道行为,并且绝对是 pty 所必需的。

我同意 James 的观点,即运行时可能有问题,但我也同意 cygwin 应该能够处理这些场景。

你们之间的完全协议不会产生太大的影响。Cygwin 源代码不会因投票而改变。

即使这个问题最终以某种方式得到解决——谁知道呢——他们可能会在 3 个月内破坏其他东西,并且不关心修复回归。他们可能会考虑一个补丁,但我需要很长时间才能找出可行的方法。我认为我的时间最好花在其他地方,因为很明显他们非常愿意破坏与本机 Win32 应用程序的兼容性,并且不想浪费更多时间让 Win32 应用程序正常工作。所以我猜 Cygwin 不应该被认为是混合 Win32/Cygwin 环境的稳定平台——我的选择是什么?我应该从哪里开始以避免完全重写为 bash 以外的东西?我只使用基本 Cygwin 安装 + 一些基本 perl 脚本。

更新: 发布这个原始问题后,他们最终pipe_byte在环境变量中做了一个新标志CYGWIN:查看文档。如果设置了这个标志,它将解决上面讨论的问题。调用非 Cygwin Win32 程序时,请始终确保pipe_byte设置了标志。

但是,我后来发现与 .NET Framework 4.0 和 Cygwin 不兼容。.NET Framework 的早期版本没有此问题。我首先在 Cygwin 邮件列表中提到了这个问题:

Cygwin 和 .NET Framework 4.0 之间的管道同步和不兼容

没有得到任何有效的回应,我进一步调查发现 Cygwin 正在创建重叠管道,这导致了问题。请注意,尝试对重叠管道使用非重叠 Win32 API 调用是未定义的,并且大多数(全部?)Win32 非 Cygwin 程序不使用标准文件句柄的重叠 I/O。我提交了一个补丁,该补丁在环境变量中创建了一个pipe_nooverlap标志,以CYGWIN防止这种情况发生:

可选择禁用重叠管道的补丁

不幸的是,他们拒绝了这个补丁,所以你永远不会在主 Cygwin DLL 中看到这个:

回复:补丁可选择禁用重叠管道

拒绝补丁的理由:

  1. 暗示我破坏了 Cygwin 中的信号实现;我没有发现这种情况,因为信号仍然使用重叠的管道。
  2. 他们不想添加环境变量标志,即使它显然是在解决问题。
  3. 他们不想支持甚至可以选择使用非重叠管道的代码。

以这样的推理和态度,恐怕我想不出任何办法来更改补丁以适应他们的要求……他们似乎决心禁止使用非重叠管道。我已经使用该补丁一段时间了,并且没有遇到任何问题。另外,我想不出pipe_nooverlap标志会破坏的任何情况(请参阅我在他们的邮件列表上的后续电子邮件),但我将其作为标志留下以防万一出现麻烦。

因此,如果要从 Cygwin 调用非 Cygwin Win32 或 .NET Framework 程序,则需要执行以下操作:

  1. 将我的补丁应用到您使用的任何 Cygwin 版本的源代码中。不要期望这个补丁会出现在未来的 Cygwin 版本中。
  2. 在环境变量中设置pipe_bytepipe_nooverlap标志。CYGWIN

这工作......现在!我发布这个以防它帮助其他仍然想在某些事情上使用 Cygwin 的人。

4

5 回答 5

46

我找到的最好的选择是Gow (Gnu On Windows)

它是 Cygwin 的轻量级替代品,重量轻约 10 倍。据我所知,与 Gow 一起安装的 130 个工具是常规的 Win32 应用程序。

于 2012-04-30T14:34:36.220 回答
17

2016年答案


我今年构建了Cash ,这是一个在Node.js上运行的 Linux 命令的跨平台实现。

这既支持全局安装您的每个命令path,也支持完全支持类 bash 语法、命令管道、自动完成和历史记录的交互式 shell。

这还会在 shell 中运行 win32 应用程序。

于 2016-02-27T02:53:08.563 回答
11

MSYS

“受支持”的软件包可能较少,因为您必须手动安装,但不会有:

  • 路径问题(cygpath不是解决方案,因为你不能总是把它塞进去)
  • 被 cygwin 软件包混淆的程序将其操作系统报告为“cygwin”
  • .dll/.so/.lib/.a 混淆

并且与 Windows 应用程序有更好的互操作性。

于 2012-10-23T04:01:46.020 回答
4

Cygnal是我创建修改后的 Cygwin 的项目,它作为旨在作为本地 Windows 程序运行的应用程序的运行时支持库,遵循 Windows 用户熟悉的外部约定。

这个想法是您可以使用完整的 Cygwin 环境进行开发,使用其默认工具链:使 Cygwin 可执行文件的编译器相同。然后,您可以通过将您的程序与cygwin1.dllCygnal 项目的修改捆绑在一起,将其部署为 Cygnal 程序。

这对于具有大量 POSIX 依赖项并且需要功能丰富、质量良好的 POSIX 实现的程序特别有用。

项目负责人似乎并不认为这是一个真正的问题,因为他们显然并不真正支持在 Cygwin 内运行非 Cygwin 程序(惊喜!)。

相比之下,在 Cygnal 项目中,这种事情被认为是一个将合并合理解决方案的问题。

于 2017-06-15T01:06:33.963 回答
3

我曾经主要将 cygwin 用于 X11 服务器功能。在远程服务器上运行任何工具并将显示导出到本地 cygwin 很有用。我发现我可以使用轻得多的 Xming 服务器来实现相同的目标。

于 2013-03-22T16:19:57.270 回答