Windows comment rediriger le paramètre du fichier vers stdout? (Équivalent Windows de `/ dev / stdout`)

12

Console Windows:

  • L'outil A peut écrire des données binaires dans un fichier, mais n'a pas la possibilité de lui dire d'utiliser stdout.
  • L'outil B peut lire les données binaires de stdin et y traiter les informations.

Comment puis-je obtenir la sortie de A par le biais de B sans utiliser de fichier intermédiaire?

En d'autres termes: quel est l'équivalent de Windows /dev/stdout?

--jeroen

Jeroen Wiert Pluimers
la source

Réponses:

18

Windows a un analogue pour / dev / stdout, CON:

J'imagine que cela fonctionne toujours, compte tenu du programme de «compatibilité hérité» de Microsoft.

Ah .. je l'ai trouvé. Le support Microsoft donne une liste de noms réservés. Vous ne pouvez pas nommer un fichier de ces noms, et ils ont des significations spéciales lorsqu'ils sont utilisés comme entrées ou sorties.

Vous POUVEZ être en mesure d'utiliser CON comme périphérique de sortie pour envoyer à stdout.

La 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
la source
1
Merci, cela fonctionne vraiment (même dans Win 8.1). Nous courons construire avec l' unité, en mode batch: Unity.exe -batchmode -projectPath C:\***\Application -logFile -buildWebPlayer web -quit. Sans argument (nom de fichier) pour -logFile- il doit imprimer la sortie sur la console, mais ce n'est pas le cas. Après avoir ajouté CON (ie - -logFile CON) - il le fait :-)
setevoy
@setevoy, cela fonctionne-t-il réellement pour vous avec Unity sur Windows? Pouvez-vous donner plus de détails? Provoque juste un crash Unity pour moi sur Windows 7 et 10 en utilisant Unity.exe -batchmode -quit -projectPath "%cd%" -logFile CON -buildWindows64Player ".\GameBuild\Generic.exe". La commande fonctionne bien sans fichier journal mais je n'obtiens aucune sortie de build.
bbodenmiller
@bbodenmiller Désolé, mais je ne peux pas fournir plus d'informations - ce projet a été terminé il y a presque 2 ans :-)
setevoy
1
@bbodenmiller Il semble que la sortie du fichier journal vers stdout soit interrompue pour le moment. Voir: issuetracker.unity3d.com/issues/…
Verox
2
La réponse est fausse. Le dispositif CON s'affiche. L'écriture dans CON ne peut être ni redirigée (comme dans program > file.txt) ni utilisée dans un canal (pour passer des données à la stdin d'un autre programme comme dans program | another_program). La sortie écrite dans CON est toujours affichée. La bonne réponse est "Windows n'a pas d'équivalent de / dev / stdout"
Egor Skriptunoff
5

Windows n'a pas d'équivalent direct /dev/stdout.


Voici ma tentative d'écrire un programme C # qui crée un canal nommé , qui peut être donné au programme A comme nom de fichier. Nécessite .NET v4.

(C # parce que le compilateur est livré avec le runtime .NET, et quel ordinateur n'a pas .NET de nos jours?)

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

Compiler avec:

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

csc peuvent être trouvés dans %SystemRoot%\Microsoft.NET\Framework64\<version>\csc.exe

Par exemple, en utilisant .NET Client Profile v4.0.30319 sur un Windows XP 32 bits:

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

Courir:

PipeServer foo in | programtwo

dans la fenêtre un, et:

programone \\.\pipe\foo

dans la fenêtre deux.

user1686
la source
+1 Voilà une solution sympa! Je vais essayer ça bientôt et je vous le ferai savoir. Maintenant, quelques Zzzzzzz :-)
Jeroen Wiert Pluimers
Une dernière réflexion avant de faire Zzzz: qu'en est-il de la fermeture du tuyau? Je vais réfléchir à ce que le meilleur mécanisme de signalisation est programoneà dire pipe, c'est fait avec\\.\pipe\foo
Jeroen Wiert Pluimers
@Jeroen: Une fois la programonesortie des données terminée, il fermera simplement le fichier de sortie qu'il utilisait. (Du côté client, les tuyaux fonctionnent de la même manière que les fichiers ordinaires.) Dans ce cas, pipe.exe- plus précisément, pipe.CopyTo(...)- atteindra EOF et quittera simplement.
user1686
@Jeroen: En outre, il y a une chose que je n'ai pas compris: lorsque vous utilisez l'outil dans le sens opposé ( out) (copiez stdin vers le tuyau), il meurt avec l'erreur "Broken pipe" après les 1 premiers Ko. Cela ne se produit pas lors de la copie d'un canal vers stdout ( in), cependant, cela ne devrait pas affecter votre programme. (Comme on dit, les correctifs sont les bienvenus. )
user1686
merci va essayer cela plus tard la semaine prochaine, quelque chose dans le projet est venu avec un prix plus élevé (n'aimez-vous pas les projets informatiques <g>)
Jeroen Wiert Pluimers
4

Sur la base de la réponse de grawity , j'ai créé une version étendue qui permet de démarrer un processus directement sans avoir à utiliser plusieurs fenêtres de terminal.

Usage général:

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

La chaîne "{pipe}" est ensuite remplacée par le chemin de redirection.

Exemple réel:

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

Cette ligne de commande peut être insérée directement dans, par exemple, Eclipse pour rediriger le journal de construction d'un certain générateur externe vers StdOut.

C'est probablement le meilleur qu'il obtienne ...

Lien

ntninja
la source