Ruby在Windows控制台的输出VS mingw64 VS cygwin64

时间:2022-06-12 01:56:47

I'm having a really weird problem here. Here's simple code that uses puts:

我有一个很奇怪的问题。下面是使用put的简单代码:

puts "Dale"
sleep 1
puts "Cooper"

I have 3 different terminals/consoles:

我有三个不同的终端/控制台:

  • Windows console (system default)
  • Windows控制台(系统默认)
  • mingw64 (UNIX-like terminal that was installed alongside with Git)
  • mingw64(与Git一起安装的类unix终端)
  • cygwin64 (UNIX-like terminal)
  • cygwin64(类unix终端)

Here is weird thing: the code runs as expected only in the standard Windows console. UNIX-like terminals are waiting for 1 second and only then showing output (both lines at the same moment). Basically, UNIX-like terminals are waiting for the program to exit, and then they are showing the final result of output.

这里有一件奇怪的事情:代码只在标准的Windows控制台运行。类unix的终端等待1秒,然后显示输出(同时两行)。基本上,类unix终端正在等待程序退出,然后显示输出的最终结果。

If I replace puts with print, it wont affect the execution process. UNIX-like terminals will still delay output until the program quits.

如果我用print替换put,它不会影响执行过程。类unix的终端仍然会延迟输出,直到程序退出。

But the next two examples work right in all 3 terminals/consoles:

但是接下来的两个例子在所有3个终端/控制台都适用:

system("echo Dale")
sleep 1
system("echo Cooper")

This one adds quotes, but aside from this, the code works as expected.

这段代码添加了引号,除此之外,代码按照预期工作。

p "Dale"
sleep 1
p "Cooper"

Having said this, I assume this has something to do with Ruby. I have tried different versions of Ruby.

说到这里,我假设这与Ruby有关。我尝试过不同版本的Ruby。

Can someone explain why this is happening and what are possible ways to bypass this issue?

有人能解释一下为什么会这样吗?有什么方法可以绕过这个问题呢?

1 个解决方案

#1


0  

Here's me answering my own question.

我来回答我自己的问题。

Little background

If you do puts STDOUT.sync before the code then you will see that no matter if you are using Windows console or UNIX-like terminal, it will say that STDOUT.sync is set to false. That's weird thing because Windows console is flushing output immediately and UNIX-like terminals don't. I'm not sure why that's happening.

如果你这样做了,你就会被淘汰。在代码之前同步,您将看到,无论您是使用Windows控制台还是类unix终端,它都将显示STDOUT。同步设置为false。这很奇怪,因为Windows控制台会立即刷新输出,而类unix终端则不会。我不知道为什么会这样。

Solution

You can do STDOUT.flush (or $stdout.flush) to flush buffer or you can set STDOUT.sync (or $stdout.sync) to true. Both variants are completely friendly with Windows console. So the code will be as following:

你可以做STDOUT。刷新(或$ STDOUT. flush)以刷新缓冲区或设置STDOUT。同步(或$stdout.sync)到true。这两种变体都与Windows控制台完全友好。所以代码如下:

puts "Dale"
STDOUT.flush
sleep 1
puts "Cooper"

or more recommended:

或更多的建议:

STDOUT.sync = true
puts "Dale"
sleep 1
puts "Cooper"

Determining whenever it's Windows console or UNIX-like terminal

Here is a little trick suggested by @eryksun to know if code is being runned in Windows console or UNIX-like terminal. STDOUT.isatty works kind of inverted when runned under Windows, but nevertheless it does the trick.

下面是@eryksun建议的一个小技巧,可以知道代码是否在Windows控制台或类unix终端中运行。STDOUT。当在Windows下运行时,isatty的工作方式是倒转的,但它却能做到这一点。

if STDOUT.isatty
    # Windows console
else
    # UNIX-like terminal
end

Keep in mind that this assumes that you already know that the code is being runned under Windows. A good way to check OS is described here.

请记住,这假定您已经知道代码在Windows下运行。这里描述了一种检查OS的好方法。

References

Major source for the answer can be found here. Idea for the answer belongs to @eryksun.

答案的主要来源可以在这里找到。答案是@eryksun。

STDOUT.sync, STDOUT.sync = (question about this method), STDOUT.flush, STDOUT.isatty.

STDOUT。同步,STDOUT。sync =(关于这个方法的问题),STDOUT。冲洗,STDOUT.isatty。

#1


0  

Here's me answering my own question.

我来回答我自己的问题。

Little background

If you do puts STDOUT.sync before the code then you will see that no matter if you are using Windows console or UNIX-like terminal, it will say that STDOUT.sync is set to false. That's weird thing because Windows console is flushing output immediately and UNIX-like terminals don't. I'm not sure why that's happening.

如果你这样做了,你就会被淘汰。在代码之前同步,您将看到,无论您是使用Windows控制台还是类unix终端,它都将显示STDOUT。同步设置为false。这很奇怪,因为Windows控制台会立即刷新输出,而类unix终端则不会。我不知道为什么会这样。

Solution

You can do STDOUT.flush (or $stdout.flush) to flush buffer or you can set STDOUT.sync (or $stdout.sync) to true. Both variants are completely friendly with Windows console. So the code will be as following:

你可以做STDOUT。刷新(或$ STDOUT. flush)以刷新缓冲区或设置STDOUT。同步(或$stdout.sync)到true。这两种变体都与Windows控制台完全友好。所以代码如下:

puts "Dale"
STDOUT.flush
sleep 1
puts "Cooper"

or more recommended:

或更多的建议:

STDOUT.sync = true
puts "Dale"
sleep 1
puts "Cooper"

Determining whenever it's Windows console or UNIX-like terminal

Here is a little trick suggested by @eryksun to know if code is being runned in Windows console or UNIX-like terminal. STDOUT.isatty works kind of inverted when runned under Windows, but nevertheless it does the trick.

下面是@eryksun建议的一个小技巧,可以知道代码是否在Windows控制台或类unix终端中运行。STDOUT。当在Windows下运行时,isatty的工作方式是倒转的,但它却能做到这一点。

if STDOUT.isatty
    # Windows console
else
    # UNIX-like terminal
end

Keep in mind that this assumes that you already know that the code is being runned under Windows. A good way to check OS is described here.

请记住,这假定您已经知道代码在Windows下运行。这里描述了一种检查OS的好方法。

References

Major source for the answer can be found here. Idea for the answer belongs to @eryksun.

答案的主要来源可以在这里找到。答案是@eryksun。

STDOUT.sync, STDOUT.sync = (question about this method), STDOUT.flush, STDOUT.isatty.

STDOUT。同步,STDOUT。sync =(关于这个方法的问题),STDOUT。冲洗,STDOUT.isatty。