Windows come reindirizzare i parametri del file su stdout? (Equivalente di Windows di `/ dev / stdout`)


12

Console di Windows:

  • Lo strumento A può scrivere dati binari in un file, ma non ha alcuna opzione per dirgli di usare stdout.
  • Lo strumento B può leggere dati binari da stdin ed elaborare le informazioni in esso.

Come posso ottenere l'output da A inviato tramite B senza utilizzare un file intermedio?

In altre parole: qual è l'equivalente di Windows /dev/stdout?

--jeroen

Risposte:


18

Windows ha un analogo per / dev / stdout, CON:

Immagino che funzioni ancora, considerando il programma di "compatibilità legacy" in corso di Microsoft.

Ah .. l'ho trovato. Il supporto tecnico Microsoft fornisce un elenco di nomi riservati. Non è possibile assegnare un nome a un file con questi nomi e hanno significati speciali se utilizzati come input o output.

POTREBBE essere in grado di utilizzare CON come dispositivo di output da inviare a stdout.

La lista:

   Name    Function
   ----    --------
   CON     Keyboard and display
   PRN     System list device, usually a parallel port
   AUX     Auxiliary device, usually a serial port
   CLOCK$  System real-time clock
   NUL     Bit-bucket device
   A:-Z:   Drive letters
   COM1    First serial communications port
   LPT1    First parallel printer port
   LPT2    Second parallel printer port
   LPT3    Third parallel printer port
   COM2    Second serial communications port
   COM3    Third serial communications port
   COM4    Fourth serial communications port

1
Grazie, funziona davvero (anche in Win 8.1). Corriamo costruire con Unity, in modalità batch: Unity.exe -batchmode -projectPath C:\***\Application -logFile -buildWebPlayer web -quit. Senza argomento (nome file) su -logFile- deve stampare l'output sulla console, ma non lo fa. Dopo aver aggiunto CON (cioè - -logFile CON) - fa :-)
setevoy

@setevoy funziona davvero con Unity su Windows? Puoi fornire maggiori dettagli? Mi causa solo l'arresto anomalo di Unity su Windows 7 e 10 Unity.exe -batchmode -quit -projectPath "%cd%" -logFile CON -buildWindows64Player ".\GameBuild\Generic.exe". Il comando funziona bene senza file di registro ma non ottengo alcun output di generazione.
bbodenmiller

@bbodenmiller Siamo spiacenti, ma non posso fornire ulteriori informazioni - questo progetto è stato completato quasi 2 anni fa :-)
setevoy

1
@bbodenmiller Sembra che al momento l'output del file di registro su stdout sia rotto. Vedi: issuetracker.unity3d.com/issues/…
Verox

2
La risposta è sbagliata Viene visualizzato il dispositivo CON. La scrittura su CON non può essere né reindirizzata (come in program > file.txt) né utilizzata in una pipe (per passare i dati allo stdin di un altro programma come in program | another_program). L'output scritto in CON viene sempre visualizzato. La risposta corretta è "Windows non ha un equivalente di / dev / stdout"
Egor Skriptunoff

5

Windows non ha equivalenti diretti a /dev/stdout.


Ecco il mio tentativo di scrivere un programma C # che crea una pipe denominata , che può essere data al programma A come nome file. Richiede .NET v4.

(C # perché il compilatore viene fornito con .NET runtime e quale computer non ha .NET in questi giorni?)

PipeServer.cs

using System;
using System.IO;
using System.IO.Pipes;

class PipeServer {
    static int Main(string[] args) {
        string usage = "Usage: PipeServer <name> <in | out>";
        if (args.Length != 2) {
            Console.WriteLine(usage);
            return 1;
        }

        string name = args[0];
        if (String.Compare(args[1], "in") == 0) {
            Pipe(name, PipeDirection.In);
        }
        else if (String.Compare(args[1], "out") == 0) {
            Pipe(name, PipeDirection.Out);
        }
        else {
            Console.WriteLine(usage);
            return 1;
        }
        return 0;
    }

    static void Pipe(string name, PipeDirection dir) {
        NamedPipeServerStream pipe = new NamedPipeServerStream(name, dir, 1);
        pipe.WaitForConnection();
        try {
            switch (dir) {
                case PipeDirection.In:
                    pipe.CopyTo(Console.OpenStandardOutput());
                    break;
                case PipeDirection.Out:
                    Console.OpenStandardInput().CopyTo(pipe);
                    break;
                default:
                    Console.WriteLine("unsupported direction {0}", dir);
                    return;
            }
        } catch (IOException e) {
            Console.WriteLine("error: {0}", e.Message);
        }
    }
}

Compilare con:

csc PipeServer.cs /r:System.Core.dll

csc può essere trovato in %SystemRoot%\Microsoft.NET\Framework64\<version>\csc.exe

Ad esempio, utilizzando .NET Client Profile v4.0.30319 su un Windows XP a 32 bit:

"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\csc.exe" PipeServer.cs /r:System.Core.dll

Correre:

PipeServer foo in | programtwo

nella finestra uno e:

programone \\.\pipe\foo

nella finestra due.


+1 Ora questa è una soluzione interessante! Ci proverò presto e ti farò sapere. Ora prima alcuni Zzzzzzz :-)
Jeroen Wiert Pluimers

Un altro pensiero prima di fare Zzzz: che ne dici di chiudere la pipa? Sto per pensare a quale sia il miglior meccanismo di segnalazione programoneda dire pipe, con cui è fatto\\.\pipe\foo
Jeroen Wiert Pluimers,

@Jeroen: Una volta terminato l' programoneoutput dei dati, chiuderà semplicemente il file di output che stava utilizzando. (Dal lato client, le pipe funzionano allo stesso modo dei normali file.) Quando lo fa, pipe.exe- più precisamente, pipe.CopyTo(...)- raggiungerà EOF e semplicemente uscirà.
user1686

@Jeroen: Inoltre, c'è una cosa che non ho capito: quando si utilizza lo strumento nella outdirezione opposta ( ) (copia stdin in pipe), muore con errore "Broken pipe" dopo i primi 1 kB. Non succede quando si copia una pipe su stdout ( in), tuttavia, quindi non dovrebbe influire sul programma. (Come si
suol

grazie ci proverò più tardi la prossima settimana, qualcosa nel progetto ha prodotto un prio più alto (non amate i progetti IT <g>)
Jeroen Wiert Pluimers

4

Basato sulla gravità della risposta di ho creato una versione estesa che consente di avviare direttamente un processo senza dover utilizzare più finestre di terminale.

Uso generale:

PipeServer [in|out] [process name] [argument 1] [argument 2] [...]

La stringa "{pipe}" viene quindi sostituita dal percorso di reindirizzamento.

Esempio nel mondo reale:

PipeServer.exe in "C:\Keil\UV4\Uv4.exe" -b "C:\Project\Project.uvproj" -j0 -o "{pipe}"

Questa riga di comando può essere inserita direttamente, ad esempio, in Eclipse per reindirizzare il registro di build di un determinato builder esterno su StdOut.

Questo è probabilmente il migliore che ottiene ...

collegamento

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.