最近重新安装 Cygwin 后,我遇到了一些奇怪的行为——正在运行的应用程序的终端输出在写入时没有显示,但会在某些条件下突然出现。
对于我的特殊情况,我正在运行一个 Django 服务器:
python manage.py runserver
当服务器启动时,这应该会向终端吐出几条状态消息,还应该显示服务器请求和回复(除了 Pythonprint
语句)。但这些都没有显示出来。
但是,当我修改 Django 应用程序的文件时,服务器会自动重新启动(应该如此),并且上一个会话的所有输出会突然出现。
先前安装的 Cygwin 运行良好。
我知道的唯一区别是,以前的安装使用 Cygwin Python(在 中/usr/bin
),而我的新安装使用 Windows Pyton(在 中/cygdrive/c/Python27
)。这样做是为了 MySQL 数据连接的目的。
另一个奇怪的现象(可能指向一个更大的问题)是,在我运行服务器后,Cygwin 需要两次点击关闭按钮(右上角的“X”)才能关闭终端窗口。第一次点击使终端变得无用,但窗口本身仍然存在;第二次点击会将其从屏幕上移除。
有没有人遇到过 Cygwin 不更新终端输出的情况并找到了方便的解决方法?
答案1
这里的问题是不同的 Python 安装和 Python 的“刷新”行为的结合。
刷新是指将某些内容从内存写入文件或屏幕。当一个设计良好的程序将某些内容写入屏幕时,它会检测到并立即将其写入(“刷新”)到屏幕上,因此可以立即看到。但是,如果程序正在写入磁盘上的文件,则对文件进行大量小写入比进行一次大写入要慢得多,因此它会“缓冲”小写入,直到有大量写入可以一次刷新到文件中。这就是 Python 所做的。
您看到的问题是 Cygwin 的 Python 知道 MinTTY 是一个终端,因此会频繁刷新到它,但 Windows Python 无法区分 MinTTY 终端和磁盘上的文件。它假设它正在写入的是文件,因此它会排队写入并分批刷新它们(应用程序重新启动将触发此操作),而不是在出现每条消息时刷新它。如果您等待的时间足够长(猜测,足以让价值 64kb 的消息排队),您也会看到它们全部同时写入屏幕。
有两种解决方案:要么找到解决 MySQL 问题的方法,以便您可以使用 Cygwin Python,要么从 Windows cmd shell 使用 Windows Python,它将被正确检测为终端,从而产生正确的刷新行为。
禁用 Python 的缓冲行为也可能会带来一些好处。如果您使用选项运行 Python -u
,或者sys.stdout.flush()
在打印语句后添加,这将阻止 Python 缓冲消息,并使其立即将其刷新到屏幕上。