Cygwin / MinTTY Falha ao atualizar a saída do terminal corretamente

2

Após uma reinstalação recente do Cygwin, tenho tido um comportamento estranho - nesse terminal, a saída de um aplicativo em execução não é exibida quando gravada, mas, de repente, surge em certas condições.

Para minha situação particular, estou executando um servidor do Django:

python manage.py runserver

Isso deve transmitir várias mensagens de status ao terminal enquanto o servidor gira, e também deve exibir as solicitações e respostas do servidor (além das declarações do Python print ). Nenhum deles está aparecendo.

No entanto, quando eu modifico um arquivo que faz parte do aplicativo Django, o servidor reinicia automaticamente (como deveria) e toda a saída aparece repentinamente para a sessão anterior.

Uma instalação anterior do Cygwin funcionou bem.

A única diferença conhecida que eu tenho é que a instalação anterior usando o Python Cygwin (em /usr/bin ) enquanto a minha nova instalação usa o Windows Pyton (em /cygdrive/c/Python27 ). Isso foi feito para fins de conectividade de dados do MySQL.

Uma peculiaridade adicional, que pode apontar para um problema maior, é que depois de executar o servidor, o Cygwin requer dois cliques no botão fechar (superior direito 'X') para fechar a janela do terminal. O primeiro clique torna o terminal inútil, mas a janela em si permanece; um segundo clique remove-o da tela.

Alguém encontrou uma situação em que o Cygwin não está atualizando a saída do terminal e localizou uma correção útil?

    
por Evil Closet Monkey 20.03.2013 / 18:40

1 resposta

3

O problema aqui é uma combinação das diferentes instalações do Python e o comportamento de "flushing" do Python.

Flushing refere-se a escrever algo da memória para o arquivo ou a tela. Quando um programa bem desenhado está escrevendo algo em uma tela, ele detecta isso e grava ("flush") na tela imediatamente, para que possa ser visto imediatamente. No entanto, se um programa estiver gravando em um arquivo no disco, fazer várias gravações pequenas em um arquivo é muito mais lento do que fazer um grande, então ele "armazena" pequenas gravações até que haja uma parte delas para liberar o arquivo em uma vez. Isso é o que o Python faz.

O problema que você está vendo é que o Python do Cygwin entende que o MinTTY é um terminal, e então o descarrega com freqüência, mas o Windows Python não pode dizer a diferença entre um terminal MinTTY e um arquivo no disco. Ele presume o que está gravando em um arquivo, por isso, ele grava as filmagens e libera-as em lotes (a reinicialização do aplicativo acionará isso), em vez de liberar cada mensagem como aparece. Se você esperasse o tempo suficiente (em um palpite, o suficiente para 64kb de mensagens a serem enfileiradas), você veria todas elas sendo escritas na tela de uma só vez também.

Existem duas soluções: encontrar uma maneira de contornar os problemas do MySQL para usar o Cygwin Python ou usar o Windows Python a partir de um shell do Windows cmd, que seria corretamente detectado como um terminal e produzir o fluxo correto comportamento.

Você também pode ter alguma sorte ao desativar o comportamento de buffer do Python. Se você executar o Python com uma opção -u ou adicionar sys.stdout.flush() após instruções de impressão, isso impedirá que o Python armazene mensagens e faça com que elas sejam exibidas na tela imediatamente.

    
por 21.03.2013 / 01:12