简体   繁体   English

Cygwin 的好替代品? - Cygwin 不支持原生支持 Win32 应用程序

[英]Good alternatives to Cygwin? - Cygwin doesn't support natively support Win32 apps

Update 1/9/2014: TL;DR version: Go to bottom of this post for a way to get Cygwin to be able to call non-Cygwin programs. 2014 年 1 月 9 日更新:TL;DR 版本:转到这篇文章的底部以获取让 Cygwin 能够调用非 Cygwin 程序的方法。

After having spent the time to make some bash scripts that happen to be of significant size, newer versions of Cygwin have broken them.在花时间制作了一些碰巧很大的 bash 脚本之后,较新版本的 Cygwin 已经破坏了它们。 These scripts call into native Win32 applications that don't link with Cygwin, which is apparently not officially supported by Cygwin.这些脚本调用不与 Cygwin 链接的本机 Win32 应用程序,这显然不受 Cygwin 的官方支持。

This has come as a surprise to me, as for years I was under the impression that Cygwin could be used in a more mixed environment that combines both native non-Cygwin Win32 apps, and POSIX programs using the Cygwin compatibility layer.这让我感到惊讶,因为多年来我一直认为 Cygwin 可以在一个更加混合的环境中使用,该环境结合了本地非 Cygwin Win32 应用程序和使用 Cygwin 兼容层的 POSIX 程序。 But apparently only the POSIX compatibility layer is really supported, and if native Win32 non-Cygwin apps work then it is considered a happy coincidence.但显然只有 POSIX 兼容层真正得到支持,如果本机 Win32 非 Cygwin 应用程序工作,那么这被认为是一个快乐的巧合。

I found this out from an incompatibility I ran into with running programs compiled against the .NET Framework from within Cygwin.我从 Cygwin 中运行的针对 .NET Framework 编译的程序遇到的不兼容问题中发现了这一点。 This used to work fine, but was broken a few months ago.这曾经工作得很好,但几个月前就坏了。 Specifically, standard output from a .NET program that is piped to any other Win32 program's standard input will generally cause the receiving Win32 program to get a premature end-of-file signal because Cygwin recently switched to message pipes from byte pipes a few months ago - and message pipes appear to be incompatible with any receiving app using Visual C++ or .NET Framework.具体来说,通过管道传输到任何其他 Win32 程序标准输入的 .NET 程序的标准输出通常会导致接收 Win32 程序获得过早的文件结束信号,因为几个月前 Cygwin 最近从字节管道切换到消息管道- 并且消息管道似乎与任何使用 Visual C++ 或 .NET Framework 的接收应用程序不兼容。 This is because .NET issues a null write to the standard output, which is only passed on to the receiving app if a message pipe is used.这是因为 .NET 向标准输出发出空写入,仅在使用消息管道时才将其传递给接收应用程序。 The receiving app successfully reads zero bytes, so thinks it is end-of-file.接收应用程序成功读取零字节,因此认为它是文件结尾。 The project lead doesn't appear to consider this to be a real problem, since they apparently don't really support running non-Cygwin programs from within Cygwin (surprise!).项目负责人似乎并不认为这是一个真正的问题,因为他们显然并不真正支持在 Cygwin 内运行非 Cygwin 程序(惊喜!)。

To quote the project lead Christopher Faylor from multiple e-mails on the mailing list:从邮件列表中的多封电子邮件中引用项目负责人 Christopher Faylor 的话:

What you are seeing may be because Cygwin was changed to use message-type pipes a couple of revisions ago.您所看到的可能是因为 Cygwin 在几次修订前被更改为使用消息类型管道。 This is not going to change.这不会改变。 The change was adopted to fix a problem with Cygwin programs and those are obviously our #1 priority.采用该更改是为了解决 Cygwin 程序的问题,而这些显然是我们的第一要务。

Regardless of how many people use Visual C++ or .NET they are really not our target audience.无论有多少人使用 Visual C++ 或 .NET,他们都不是我们的目标受众。 It's nice when things work for people who don't want to use UNIX tools but they are not our primary focus.对于不想使用 UNIX 工具但它们不是我们主要关注点的人来说,这很好。 Fixing problems for people who want to use non-Cygwin stuff is not something that I find a high priority.为想要使用非 Cygwin 东西的人解决问题并不是我认为的高优先级。

From pipe.cc: Note that the write side of the pipe is opened as PIPE_TYPE_MESSAGE.来自 pipe.cc:请注意,管道的写入端以 PIPE_TYPE_MESSAGE 的形式打开。 This seems to more closely mimic Linux pipe behavior and is definitely required for pty handling since fhandler_pty_master writes to the pipe in chunks, terminated by newline when CANON mode is specified.似乎更接近于模拟 Linux 管道行为,并且对于 pty 处理肯定是必需的,因为 fhandler_pty_master 以块的形式写入管道,在指定 CANON 模式时由换行符终止。

The above comment shows an "and" relationship here.上面的评论在这里显示了“和”的关系。 Message type pipes more closely mimic Linux (UNIX) pipe behavior AND are definitely required for ptys.消息类型管道更接近地模仿 Linux (UNIX) 管道行为,并且绝对是 pty 所必需的。

I agree with James that the runtimes are probably buggy BUT I also agree that cygwin should be able to have a handle these scenarios.我同意 James 的观点,即运行时可能有问题,但我也同意 cygwin 应该能够处理这些场景。

Your complete agreement with each other is not going to have much effect.你们之间的完全协议不会产生太大的影响。 Cygwin source code is not changed by voting. Cygwin 源代码不会因投票而改变。

Even if this one issue is ultimately fixed somehow - who knows - they might break something else in 3 months and not care to fix the regression.即使这个问题最终以某种方式得到解决——谁知道呢——他们可能会在 3 个月内破坏其他东西,并且不关心修复回归。 They might consider a patch, but it would take me quite awhile to figure out something that works.他们可能会考虑一个补丁,但我需要很长时间才能找出可行的方法。 I think my time is better spent elsewhere, because it's clear that they are quite willing to break compatibility with native Win32 apps and don't want to waste more time on getting Win32 apps to work.我认为我的时间最好花在其他地方,因为很明显他们非常愿意破坏与本机 Win32 应用程序的兼容性,并且不想浪费更多时间让 Win32 应用程序正常工作。 So I guess Cygwin shouldn't be considered a stable platform for mixed Win32/Cygwin environments - what are my alternatives?所以我猜 Cygwin 不应该被认为是混合 Win32/Cygwin 环境的稳定平台——我的选择是什么? Where should I start that would avoid a complete rewrite into something other than bash?我应该从哪里开始以避免完全重写为 bash 以外的东西? I don't use more than the base Cygwin installation + some basic perl scripts.我只使用基本 Cygwin 安装 + 一些基本 perl 脚本。

UPDATE: After the posting of this original question, they did eventually a new pipe_byte flag in the CYGWIN environment variable: look at the documentation.更新:发布这个原始问题后,他们最终在CYGWIN环境变量中添加了一个新的pipe_byte标志:查看文档。 If this flag is set, it will fix the problem discussed above.如果设置了这个标志,它将解决上面讨论的问题。 When invoking a non-Cygwin Win32 program, always make sure that the pipe_byte flag is set.调用非 Cygwin Win32 程序时,请始终确保设置了pipe_byte标志。

However, I have since uncovered an incompatibility with .NET Framework 4.0 and Cygwin.但是,我后来发现与 .NET Framework 4.0 和 Cygwin 不兼容。 Previous versions of .NET Framework don't have this issue. .NET Framework 的早期版本没有此问题。 I mentioned the issue first on the Cygwin mailing list here:我首先在 Cygwin 邮件列表中提到了这个问题:

Pipe syncronization and incompatibility between Cygwin and .NET Framework 4.0 Cygwin 和 .NET Framework 4.0 之间的管道同步和不兼容

Getting no fruitful responses, I investigated further and found that Cygwin is creating overlapped pipes, which causes the problem.没有得到任何有效的回应,我进一步调查发现 Cygwin 正在创建重叠管道,这导致了问题。 Note that trying to use non-overlapped Win32 API calls with an overlapped pipe is undefined, and most (all?) Win32 non-Cygwin programs don't use overlapped I/O with their standard file handles.请注意,尝试对重叠管道使用非重叠 Win32 API 调用是未定义的,并且大多数(全部?)Win32 非 Cygwin 程序不使用其标准文件句柄的重叠 I/O。 I submitted a patch that creates a pipe_nooverlap flag in the CYGWIN environment variable that prevents this from happening:我提交了一个补丁,它在CYGWIN环境变量中创建了一个pipe_nooverlap标志,以防止这种情况发生:

Patch to optionally disable overlapped pipes可选择禁用重叠管道的补丁

Unfortunately, they have rejected the patch, so you'll never see this in the main Cygwin DLL:不幸的是,他们拒绝了这个补丁,所以你永远不会在主 Cygwin DLL 中看到这个:

Re: Patch to optionally disable overlapped pipes回复:补丁可选择禁用重叠管道

The reasoning for rejecting the patch:拒绝补丁的理由:

  1. It was implied that I broke the signal implementation in Cygwin;暗示我破坏了 Cygwin 中的信号实现; I have not found this to be the case, as signals still use overlapped pipes.我没有发现这种情况,因为信号仍然使用重叠的管道。
  2. They don't feel like adding an environment variable flag, even though it is apparently fixing problems.他们不想添加环境变量标志,即使它显然是在解决问题。
  3. They don't want to support code that even has the option of having non-overlapped pipes.他们不想支持甚至可以选择使用非重叠管道的代码。

With reasoning and attitudes like this, I'm afraid I can't think of any way to change the patch to suit their requirements... they seem determined to forbid non-overlapped pipes from ever being used.以这样的推理和态度,恐怕我想不出任何办法来更改补丁以适应他们的要求……他们似乎决心禁止使用非重叠管道。 I have been using the patch for awhile now, and have not had any problems with it.我已经使用该补丁一段时间了,并且没有遇到任何问题。 Also, I can't think of any situations that the pipe_nooverlap flag will break (see my follow-up e-mail on their mailing list), but I left it as a flag just in case there is trouble.此外,我想不出pipe_nooverlap标志会破坏的任何情况(请参阅我在他们的邮件列表上的后续电子邮件),但我将其作为标志保留以防万一出现问题。

So, if you want to call non-Cygwin Win32 or .NET Framework programs from Cygwin, you need to do the following:因此,如果要从 Cygwin 调用非 Cygwin Win32 或 .NET Framework 程序,则需要执行以下操作:

  1. Apply my patch to the source of whatever Cygwin version you are using.将我的补丁应用到您使用的任何 Cygwin 版本的源代码中。 Do not expect this patch to show up in future Cygwin versions.不要期望这个补丁会出现在未来的 Cygwin 版本中。
  2. Set the pipe_byte and pipe_nooverlap flags in the CYGWIN environment variable.CYGWIN环境变量中设置pipe_bytepipe_nooverlap标志。

This works... for now!!!这工作......现在! I post this in case it helps anyone else who still wants to use Cygwin for some things.我发布这个以防它帮助其他仍然想在某些事情上使用 Cygwin 的人。

The best alternative I found is Gow (Gnu On Windows) .我找到的最好的选择是Gow (Gnu On Windows)

It's a lightweight alternative to Cygwin, about 10 times lighter.它是 Cygwin 的轻量级替代品,重量轻约 10 倍。 As far as I know the 130 tools installed with Gow are regular Win32 applications.据我所知,与 Gow 一起安装的 130 个工具是常规的 Win32 应用程序。

2016 Answer 2016年答案


I built Cash this year, a cross-platform implementation of Linux commands running on Node.js .我今年构建了Cash ,这是一个在Node.js上运行的 Linux 命令的跨平台实现。

This supports both global installations of each command in your path , or an interactive shell with full support for bash-like syntax, command piping, autocompletion and history.这既支持path中每个命令的全局安装,也支持完全支持类 bash 语法、命令管道、自动完成和历史记录的交互式 shell。

This additionally runs win32 apps within the shell.这还会在 shell 中运行 win32 应用程序。

MSYS MSYS

There may be fewer "supported" packages, in that you have to install things by hand, but there won't be: “受支持”的软件包可能较少,因为您必须手动安装,但不会有:

  • Path issues ( cygpath is a non-solution, as you can't always shove it in)路径问题( cygpath是一个非解决方案,因为你不能总是把它塞进去)
  • Programs confused by cygwin packages reporting their OS as 'cygwin'被 cygwin 软件包混淆的程序将其操作系统报告为“cygwin”
  • .dll/.so/.lib/.a confusion .dll/.so/.lib/.a 混淆

And there is much better interop with windows applications.并且与 Windows 应用程序有更好的互操作性。

Cygnal is my project to create a modified Cygwin, serving as a run-time support library for applications intended to run as native Windows programs, following external conventions familiar to Windows users. Cygnal是我创建修改后的 Cygwin 的项目,它作为旨在作为本地 Windows 程序运行的应用程序的运行时支持库,遵循 Windows 用户熟悉的外部约定。

The idea is that you can use the full Cygwin environment to develop, using its default toolchain: the same compiler that makes Cygwin executables.这个想法是您可以使用完整的 Cygwin 环境进行开发,使用其默认工具链:使 Cygwin 可执行文件的编译器相同。 Then you can deploy your program as a Cygnal program by bundling it with the modified cygwin1.dll from the Cygnal project.然后,您可以将您的程序与 Cygnal 项目中修改后的cygwin1.dll捆绑在一起,将其部署为 Cygnal 程序。

This is especially useful for programs that have a lot of POSIX dependencies and need a decently feature-rich, good quality POSIX implementation.这对于具有大量 POSIX 依赖项并且需要功能丰富、质量良好的 POSIX 实现的程序特别有用。

The project lead doesn't appear to consider this to be a real problem, since they apparently don't really support running non-Cygwin programs from within Cygwin (surprise!).项目负责人似乎并不认为这是一个真正的问题,因为他们显然并不真正支持在 Cygwin 内运行非 Cygwin 程序(惊喜!)。

By contrast, in the Cygnal project, this sort of thing is considered an issue for which a reasonable solution will be merged.相比之下,在 Cygnal 项目中,这种事情被认为是一个将合并合理解决方案的问题。

I used to use cygwin mainly for the X11 server feature.我曾经主要将 cygwin 用于 X11 服务器功能。 It was useful to run any tools on a remote server and export the display to local cygwin.在远程服务器上运行任何工具并将显示导出到本地 cygwin 很有用。 I find that I can achieve the same thing using Xming server which is a lot lighter.我发现我可以使用轻得多的 Xming 服务器来实现相同的目标。

2022 answer 2022答案


This is the simplest and most lightweight method to get Linux commands on Windows.这是在 Windows 上获取 Linux 命令的最简单、最轻量的方法。

  1. Install the command-line installer for Windows scoop.sh安装 Windows scoop.sh的命令行安装程序

  2. Install busybox using scoop使用 scoop 安装busybox

    scoop install busybox舀安装busybox

You now have access to a ton of Linux commands.您现在可以访问大量 Linux 命令。 The commands are available across different terminals, for example cmd, Tabby, Hyper or some other terminal.这些命令可用于不同的终端,例如 cmd、Tabby、Hyper 或其他一些终端。

Example of using Linux commands on Tabby and cmd:在 Tabby 和 cmd 上使用 Linux 命令的示例:

在此处输入图像描述

Some of the available commands:一些可用的命令:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM