Cygwin的好替代品? – Cygwin不支持本地支持Win32应用程序

更新1/9/2014:TL; DR版本:转到这篇文章的底部,让Cygwin能够调用非Cygwin程序。

在花了一些时间来制作一些大小合适的bash脚本后,新版本的Cygwin已经打破了它们。 这些脚本调用本机Win32应用程序,不与Cygwin链接,Cygwin显然不被Cygwin正式支持。

这对我来说是一个惊喜,因为多年来,我一直认为Cygwin可以用于混合了本机非Cygwin Win32应用程序和使用Cygwin兼容层的POSIX程序的混合环境。 但显然只有POSIX兼容层才真正被支持,如果本机Win32非Cygwin应用程序工作,那么它被认为是一个幸福的巧合。

我遇到了一个不兼容的问题,我在Cygwin中运行了针对.NET Framework编译的程序。 这曾经工作得很好,但几个月前被打破。 具体来说,从.NET程序传输到任何其他Win32程序的标准input的标准输出通常会导致接收Win32程序过早结束文件信号,因为Cygwin最近在几个月前从字节pipe道切换到消息pipe道 – 并且消息pipe道似乎与使用Visual C ++或.NET Framework的任何接收应用程序不兼容。 这是因为.NET向标准输出发出空写,如果使用消息pipe道,则只输出到接收应用程序。 接收应用程序成功读取零字节,所以认为它是文件结束。 项目负责人似乎并不认为这是一个真正的问题,因为他们显然不支持从Cygwin中运行非Cygwin程序(惊喜!)。

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

你所看到的可能是因为Cygwin被改为使用消息typespipe道几个修订前。 这不会改变。 这个改变被用来解决Cygwin程序的一个问题,这显然是我们的首要任务。

不pipe有多less人使用Visual C ++或.NET,他们真的不是我们的目标受众。 对于那些不想使用UNIX工具但不是我们主要关注点的人来说,这很好。 为那些想要使用非Cygwin的人修复问题并不是我认为最重要的事情。

从pipe.cc:请注意,pipe道的写入侧打开为PIPE_TYPE_MESSAGE。 这似乎更接近模仿Linuxpipe道行为,并且对于pty处理来说肯定是必需的,因为当指定CANON模式时,fhandler_pty_master以块forms写入pipe道,以换行符结尾。

上面的评论显示了一个“和”的关系。 消息typespipe道更加模仿Linux(UNIX)pipe道行为,并且对于ptys来说绝对是必需的。

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

你们之间的完整协议不会有太大的影响。 Cygwin源代码不会被投票改变。

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

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

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

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

得到没有富有成效的答复,我进一步调查,发现Cygwin正在创build重叠的pipe道,这导致了问题。 请注意,尝试使用重叠pipe道的非重叠Win32 API调用未定义,并且大多数(所有?)Win32非Cygwin程序都不使用与其标准文件句柄重叠的I / O。 我提交了一个补丁,它在CYGWIN环境variables中创build了一个pipe_nooverlap标志,以防止这种情况发生:

修补以select性地禁用重叠的pipe道

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

Re:修补可选地禁用重叠的pipe道

拒绝补丁的理由:

  1. 这意味着我打破了Cygwin的信号实现; 我还没有发现这种情况,因为信号仍然使用重叠的pipe道。
  2. 他们不想添加一个环境variables标志,即使它显然是解决问题。
  3. 他们不想支持甚至可以select非重叠pipe道的代码。

有了这样的推理和态度,恐怕我想不出有什么办法来改变补丁来满足他们的要求…他们似乎决心禁止不重叠的pipe道被使用。 我已经使用了一段时间的补丁,并没有任何问题。 另外,我想不出任何pipe_nooverlap标志会中断的情况(请参阅我的邮件列表中的后续电子邮件),但是为了防止出现问题,我将其作为标志保留。

所以,如果你想从Cygwin中调用非Cygwin Win32或者.NET Framework程序,你需要执行以下操作:

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

这工作…现在! 我发布这个以防止其他人仍然希望使用Cygwin来处理某些事情。

我发现的最佳select是Gow(Gnu On Windows) 。

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

2016答案


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

这支持path中每个命令的全局安装,或支持bash类语法,命令pipe道,自动完成和历史logging的交互式shell。

这额外运行shell中的win32应用程序。

MSYS

可能有更less的“支持”包,因为你必须手动安装,但不会有:

  • path问题( cygpath是一个非解决scheme,因为你不能总是推它)
  • 被cygwin软件包困惑的程序报告他们的操作系统为“cygwin”
  • .dll / .so / .lib / .a混淆

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

我曾经使用cygwin主要用于X11服务器function。 在远程服务器上运行任何工具并将显示导出到本地的cygwin是非常有用的。 我发现使用Xming服务器可以达到同样的效果。

Cygnal是我的项目,创build一个修改后的Cygwin,作为Windows应用程序的运行时支持库,用于Windows用户熟悉的外部约定。

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

这对于那些有许多POSIX依赖关系,需要一个function丰富,质量良好的POSIX实现的程序特别有用。

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

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