Windows, wie man Dateiparameter zu stdout umleitet? (Windows-Äquivalent von "/ dev / stdout")

12

Windows-Konsole:

  • Tool A kann Binärdaten in eine Datei schreiben, hat jedoch keine Option, die Verwendung von stdout anzuweisen.
  • Tool B kann Binärdaten aus stdin lesen und die darin enthaltenen Informationen verarbeiten.

Wie kann ich die Ausgabe von A durch B leiten, ohne eine Zwischendatei zu verwenden?

Mit anderen Worten: Wovon ist das Windows-Äquivalent /dev/stdout?

- Jeroen

Jeroen Wiert Pluimers
quelle

Antworten:

18

Windows hat eine Entsprechung für / dev / stdout, CON:

Ich stelle mir vor, es funktioniert immer noch, wenn man das laufende "Legacy Compatibility" -Programm von Microsoft berücksichtigt.

Ah .. fand es. Microsoft Support gibt eine Liste reservierter Namen an. Sie können einer Datei keinen Namen geben. Diese Namen haben bei der Verwendung als Ein- oder Ausgänge eine besondere Bedeutung.

Möglicherweise können Sie CON als Ausgabegerät zum Senden an stdout verwenden.

Die Liste:

   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
Lornix
quelle
1
Danke, es funktioniert wirklich (auch in Win 8.1). Wir betreiben Build mit Unity, im Batch - Modus: Unity.exe -batchmode -projectPath C:\***\Application -logFile -buildWebPlayer web -quit. Ohne Argument (Dateiname) für -logFile- muss die Ausgabe an die Konsole ausgegeben werden, dies ist jedoch nicht der Fall. Nach dem Hinzufügen von CON (dh - -logFile CON) - tut es :-)
setevoy
@setevoy funktioniert das eigentlich bei dir mit Unity unter Windows? Können Sie mehr Details angeben? Verursacht nur Unity-Absturz für mich unter Windows 7 und 10 mit Unity.exe -batchmode -quit -projectPath "%cd%" -logFile CON -buildWindows64Player ".\GameBuild\Generic.exe". Befehl funktioniert gut ohne Protokolldatei, aber ich bekomme keine Build-Ausgabe.
bbodenmiller
@bbodenmiller Leider können wir keine weiteren Informationen bereitstellen - dieses Projekt wurde vor fast 2 Jahren abgeschlossen :-)
setevoy
1
@bbodenmiller Die Ausgabe der Logdatei auf stdout ist momentan fehlerhaft. Siehe: issuetracker.unity3d.com/issues/…
Verox
2
Die Antwort ist falsch. CON-Gerät wird angezeigt. Das Schreiben in CON konnte weder umgeleitet (wie in program > file.txt) noch in einer Pipe verwendet werden (um Daten wie in an die Standardeingabe eines anderen Programms zu übergeben program | another_program). Der in CON geschriebene Ausgang wird immer angezeigt. Die richtige Antwort lautet: "Windows hat kein Äquivalent zu / dev / stdout"
Egor Skriptunoff
5

Windows hat keine direkte Entsprechung zu /dev/stdout.


Hier ist mein Versuch, ein C # -Programm zu schreiben, das eine Named Pipe erzeugt , die Programm A als Dateinamen gegeben werden kann. Benötigt .NET v4.

(C #, weil der Compiler mit .NET-Laufzeit ausgeliefert wird und auf welchem ​​Computer derzeit .NET nicht verfügbar ist?)

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);
        }
    }
}

Kompilieren mit:

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

csc kann gefunden werden in %SystemRoot%\Microsoft.NET\Framework64\<version>\csc.exe

Beispiel: Verwenden von .NET Client Profile v4.0.30319 unter 32-Bit-Windows XP:

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

Lauf:

PipeServer foo in | programtwo

in Fenster eins und:

programone \\.\pipe\foo

in Fenster zwei.

user1686
quelle
+1 Das ist eine coole Lösung! Ich werde es bald versuchen und dich wissen lassen. Jetzt erstmal
Zzzzzzz
Noch ein Gedanke, bevor Sie Zzzz machen: Was ist mit dem Schließen der Pfeife? Ich werde darüber nachdenken, was der beste Signalmechanismus ist, um programonezu sagen pipe, dass es mit\\.\pipe\foo
Jeroen Wiert Pluimers
@Jeroen: Wenn programonedie Datenausgabe abgeschlossen ist, wird die verwendete Ausgabedatei einfach geschlossen. (Auf der Clientseite funktionieren Pipes genauso wie normale Dateien.) Wenn dies der Fall ist, wird pipe.exe- genauer gesagt pipe.CopyTo(...)- EOF erreicht und einfach beendet.
user1686
@Jeroen: Außerdem gibt es eine Sache, die ich nicht herausgefunden habe: Wenn Sie das Werkzeug in der entgegengesetzten ( out) Richtung verwenden (stdin in Pipe kopieren), stirbt es nach den ersten 1 kB mit dem Fehler "Pipe gebrochen". Tritt jedoch nicht auf, wenn eine Pipe nach stdout ( in) kopiert wird , sodass Ihr Programm davon nicht betroffen sein sollte. (Wie sie sagen, Patches willkommen. )
User1686
danke werde es später in der nächsten Woche versuchen, etwas in dem Projekt kam mit einem höheren Preis (nicht lieben Sie IT-Projekte <g>)
Jeroen Wiert Pluimers
4

Basierend auf der Antwort von grawity habe ich eine erweiterte Version erstellt, mit der ein Prozess direkt gestartet werden kann, ohne mehrere Terminalfenster verwenden zu müssen.

Allgemeine Verwendung:

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

Die Zeichenfolge "{pipe}" wird dann durch den Umleitungspfad ersetzt.

Beispiel aus der Praxis:

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

Diese Befehlszeile kann beispielsweise direkt in Eclipse eingefügt werden, um das Build-Protokoll eines bestimmten externen Builders nach StdOut umzuleiten.

Dies ist wahrscheinlich das Beste, was es gibt ...

Verknüpfung

ntninja
quelle