Domanda

Ho avuto l'impressione che i processi sul sistema operativo hanno tre flussi standard: stdin, stdout, and stderr. Ho anche pensato che gli editor di testo come il lavoro vim prendendo in ingresso nel corso stdin e l'invio di caratteri di escape ANSI sopra stdout. Tuttavia, la mia visione di come interpreti della riga di comando non è in possesso in questo caso uno:

Quando faccio funzionare l'ordine C:\cygwin\bin\bash.exe, sono richiamato con:

Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\masson>C:\cygwin\bin\bash.exe
bash-3.2$ 

... ma quando l'eseguo in Java con il seguente frammento, il flusso stdin è vuota:

ProcessBuilder pb = new ProcessBuilder("C:\\cygwin\\bin\\bash.exe");
pb.redirectErrorStream(true);
Process proc = pb.start();
final InputStream in = proc.getInputStream();

new Thread(new Runnable() {
  public void run() {
    // Blocks forever...
    in.read(new byte[1024]);
  }
}).start();

Che cosa sta succedendo qui? Mi è stato detto che è in esecuzione in bash.exe interattivo-mode. Questo significa che i flussi standard non vengono utilizzati? Come posso ancora lavorare lavoro con questi programmi, e in ultima analisi, come avrei potuto implementare la mia versione di cmd.exe? Penso di essere qualcosa che non comprensione fondamentale di come interpreti della riga di comando funzionano ...

(Tutti i link ad articoli parlano di argomenti correlati sarebbe molto apprezzato. Non ho avuto molta fortuna ricerca. Oh, e un'ultima domanda, sono flussi standard trattati in modo diverso in Windows che nella maggior parte dei sistemi operativi Unix-like? )

È stato utile?

Soluzione

Essere in modalità interattiva non significa che i flussi standard non vengono utilizzati. Ma in questo caso, Bash è più probabile esecuzione in non modalità -interactive (è rilevare che non parla direttamente al app terminale, quindi si presuppone che è in uso a livello di codice, e quindi non stampare il benvenuto bandiera). In questo caso i flussi standard sono ancora in uso, è solo che non c'è niente di essere uscita.

Come ergosys fuori a punta, non si può davvero contare su in.read(new byte[1024]) di tornare prima che abbia letto le piene 1024 byte, anche se è probabilmente ok per supporre che sarà - tuttavia, certamente non tornare prima che sia letto almeno un byte, ed io credo che sia il problema qui - non stai ricevendo nemmeno un byte di uscita .

Prova a passare "-i" per bash per farlo funzionare nel modo interattivo.

Altri suggerimenti

Ogni programma che utilizza la libreria standard C può dire se si sta parlando con un dispositivo TTY (a.k.a riga di comando) utilizzando la funzione isatty (). Bash probabilmente rileva che sta parlando con un tubo al posto di un terminale e non fa in uscita un prompt.

Sono più un tipo Python che un ragazzo Java (quindi tutto quello che dico è veloce congetture da JavaDoc), ma sembra che si sta impostando un deadlock multi-processo.

in.read(new byte[1024]); non tornerà fino a quando non leggiamo 1024 byte di dati e bash.exe non emette un insieme di 1024 byte prima di fermarsi ad attendere per l'input. (Per fare questo, l'uso proc.getOutputStream() e dei mangimi alcuni comandi per rispondere a.)

Di conseguenza, si ottiene Java attesa di bash per rispondere e bash in attesa per Java di rispondere e sia perfettamente contento di aspettare fino alla morte dell'universo senza annoiarsi o stanco.

Il mio consiglio è di usare in.available() prima di ogni chiamata a in.read() per evitare il blocco. In questo modo, è possibile passare avanti e indietro tra l'alimentazione di dati e estraendola senza rimanere bloccati.

In realtà, probabilmente sarebbe molto più semplice e più sano per appena avvolgerlo in un BufferedReader .

Aggiornamento da commento: Inoltre, quando strumenti come bash rilevano che stdin non è un terminale (vedi la chiamata di sistema isatty), essi tampone enorme (4K o più) blocchi sul presupposto che l'ingresso è non interattiva. Non sono sicuro se ti aiuto, ma provare ad avviare bash con il flag -i.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top