2012-07-17 11 views
5

Ciao secondo this post, unbuffer, si connette a un comando tramite uno pseudo-terminale (pty), che lo rende trattato come un processo interattivo, pertanto non utilizza alcun buffer di stdout.Qual è l'equivalente del programma unbuffer su Windows?

Vorrei utilizzare questa funzione su Windows. Posso sapere qual è l'equivalente del programma unbuffer su Windows? Grazie.

+0

Non c'è alcun equivalente. Windows non ha pseudo-terminali. –

+0

@HarryJohnston Ciao Harry, vorrei usare Java per eseguire comandi esterni e leggere l'output stdout 'in tempo reale'. Alcuni programmi .exe mi stanno dando problemi a causa del buffering stdout. Non è stato possibile ottenere alcun output di stdout quando il programma è ancora in esecuzione. Quando il programma termina, ottengo improvvisamente un sacco di output stdout. (Questo programma è in grado di generare output di stdout in tempo reale quando lo eseguo manualmente nella finestra del prompt dei comandi) Come posso risolvere questo problema se non c'è uno pseudo terminale in Windows? – userpal

+0

Non è il sistema operativo che esegue il buffering, è l'applicazione. Dovrai correggere i programmi .exe in questione in modo che non memorizzino il buffer dell'output. –

risposta

2

Il comportamento che si sta descrivendo è tipico delle applicazioni che utilizzano librerie di runtime per I/O. Per impostazione predefinita, la maggior parte delle librerie di runtime verifica se l'handle è un dispositivo in modalità carattere come una console e, in tal caso, non esegue alcun buffering. (Idealmente la libreria di runtime tratterà un pipe allo stesso modo di una console, ma sembra che la maggior parte non lo faccia.)

Non sono a conoscenza di alcun modo ragionevole per ingannare tale applicazione a pensarlo sta scrivendo su una console quando in realtà sta scrivendo su una pipe.

In linea di principio, se si conosce la quantità di dati che ci si aspetta, è possibile utilizzare console API functions per creare una console per l'applicazione in cui scrivere e quindi leggere l'output dalla console. Ma non puoi farlo da Java, avresti bisogno di scrivere un'applicazione C per farlo per te.

Analogamente, in linea di principio dovrebbe essere presumibilmente possibile scrivere un driver di dispositivo equivalente a uno pseudo-terminale Unix, uno che agisce come un tubo ma si riferisce a un dispositivo in modalità carattere. Ma scrivere driver di dispositivo richiede competenze specifiche e devono essere firmati digitalmente, quindi, a meno che non esista un prodotto esistente, questo approccio non è probabilmente fattibile.

+0

Un'opzione esistente potrebbe essere l'emulatore null-modem [com0com] (http://com0com.sourceforge.net/).(Se ricordo bene, le porte seriali sono solitamente trattate come unbuffered.) –

4

Ho trascorso un po 'di tempo su questo e ci sono riuscito. Ho trovato questo blog durante la ricerca e ho deciso di tornare e fornire la mia soluzione per salvare il prossimo ragazzo qualche volta. Sto rispondendo come ospite con una e-mail falsa, quindi non interagirò, ma non dovrebbero essere richieste ulteriori informazioni.

Il 18 luglio '12 alle 19:41 Harry Johnston ha scritto:

"In linea di principio, se si sa quanti dati aspettarsi, è possibile utilizzare le funzioni della console API per creare una console per l'applicazione per scrivere a, quindi leggere l'output dalla console, ma non è possibile farlo da Java, è necessario scrivere un'applicazione C per farlo per te. "

Il fatto è che esiste già un'utilità che esegue questa operazione. È scritto per un uso leggermente diverso, ma può essere coxed nel fornire il risultato desiderato. Lo scopo previsto è di abilitare l'applicazione di una console di windows per interagire con un terminale tty in stile Linux. Lo fa eseguendo una console nascosta e accede direttamente al buffer della console. Se provassi ad usarlo, falliresti. Sono stato fortunato e ho scoperto che ci sono interruttori non documentati per questa utility che gli consentiranno di fornire un semplice output senza buffer. Senza gli interruttori fallisce con l'errore - l'output non è un tty - quando si prova a pipe output.

L'utilità è denominata winpty. È possibile ottenere qui:

https://github.com/rprichard/winpty/releases

Gli interruttori privi di documenti sono menzionati qui:

https://github.com/rprichard/winpty/issues/103

Sto utilizzando la versione MSYS2. Avrai bisogno di msys-2.0.dll per usarlo.

eseguire semplicemente:

winpty.exe -Xallow-non-tty -Xplain your_program.exe | receive_unbuffered_output.exe 

-Xallow-non-tty, permetterà l'uscita in filodiffusione

-Xplain, rimuoverà i codici di escape terminale Linux aggiunti (o come si chiama)

file richiesti sono:

winpty.exe 
winpty-agent.exe 
winpty.dll 
msys-2.0.dll 

winpt y-debugserver.exe - Non necessario

+0

sì, funziona, aiutato a risolvere questo: https://stackoverflow.com/questions/46443544/python-popen-sdtout-doesnt-get-all- la-output-quando-exe-fallisce –

0

Disclaimer: La mia risposta riguarda solo gli eseguibili compilati utilizzando MSVC.

Il criterio di buffering è codificato all'interno della libreria Microsoft C Runtime (CRT). È possibile conoscere i dettagli here. Questo articolo suggerisce di utilizzare gli handle della console e di manipolare i buffer della console per ricevere output senza buffer.

Tuttavia, c'è una funzionalità non documentata all'interno di Microsoft C Runtime di ereditare handle di file con alcuni flag interni direttamente dal suo processo padre utilizzando lpReserved2 e cbReserved2 campi di STARTUPINFO struttura. Puoi trovare i dettagli nel codice sorgente crt fornito da Microsoft Visual Studio. Oppure cerca qualcosa come posfhnd su GitHub.

È possibile sfruttare questa funzionalità non documentata per fornire un handle di pipe e specificare i flag FOPEN | FDEV per il processo figlio, in modo da ingannare il processo figlio trattando il pipe handle allo stesso modo di un handle FILE_TYPE_CHAR.

Ho un funzionamento Python3 script per dimostrare questo metodo.

Problemi correlati