Windows como redirecionar parâmetro de arquivo para stdout? (Windows equivalente a `/ dev / stdout`)


12

Console do Windows:

  • A ferramenta A pode gravar dados binários em um arquivo, mas não tem opção para dizer a ele para usar stdout.
  • A ferramenta B pode ler dados binários do stdin e processar as informações nele contidas.

Como posso obter a saída de A canalizada através de B sem usar um arquivo intermediário?

Em outras palavras: do que o Windows é equivalente /dev/stdout?

--jeroen

Respostas:


18

O Windows possui um análogo para / dev / stdout, CON:

Eu imagino que ainda funcione, considerando o programa contínuo de "compatibilidade herdada" da Microsoft.

Ah .. encontrei. O Suporte da Microsoft fornece uma lista de nomes reservados. Você não pode nomear um arquivo com esses nomes, e eles têm significados especiais quando usados ​​como entradas ou saídas.

Você PODE poder usar CON como um dispositivo de saída para enviar ao stdout.

A 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
Obrigado, ele realmente funciona (mesmo no Win 8.1). Corremos de compilação com Unity, no modo de lote: Unity.exe -batchmode -projectPath C:\***\Application -logFile -buildWebPlayer web -quit. Sem argumento (nome do arquivo) para -logFile- ele deve imprimir a saída no console, mas não. Depois de adicionar CON (ou seja, - -logFile CON) - que faz :-)
setevoy

@setevoy isso realmente funciona para você com o Unity no Windows? Você pode dar mais detalhes? Apenas causa uma falha do Unity para mim no Windows 7 e 10 usando Unity.exe -batchmode -quit -projectPath "%cd%" -logFile CON -buildWindows64Player ".\GameBuild\Generic.exe". O comando funciona bem sem o arquivo de log, mas não recebo saída de compilação.
bbodenmiller

@bbodenmiller Desculpe, mas não pode fornecer mais informações - este projeto foi concluído há quase 2 anos :-)
setevoy

1
@bbodenmiller Parece que a saída do arquivo de log para o stdout está quebrada no momento. Veja: issuetracker.unity3d.com/issues/…
Verox

2
A resposta está errada. O dispositivo CON é exibido. A gravação no CON não pode ser redirecionada (como em program > file.txt) nem usada em um canal (para passar dados para o stdin de outro programa como em program | another_program). A saída gravada em CON sempre será exibida. A resposta correta é "O Windows não tem equivalente de / dev / stdout"
Egor Skriptunoff

5

O Windows não tem equivalente direto a /dev/stdout.


Aqui está minha tentativa de escrever um programa C # que cria um pipe nomeado , que pode ser fornecido ao programa A como um nome de arquivo. Requer .NET v4.

(C # porque o compilador vem com o tempo de execução do .NET e que computador não possui o .NET atualmente?)

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

Ajuntar com:

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

csc pode ser encontrado em %SystemRoot%\Microsoft.NET\Framework64\<version>\csc.exe

Por exemplo, usando o .NET Client Profile v4.0.30319 em um Windows XP de 32 bits:

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

Corre:

PipeServer foo in | programtwo

na janela um e:

programone \\.\pipe\foo

na janela dois.


+1 Agora, essa é uma solução legal! Vou tentar isso em breve e informá-lo. Agora primeira alguns ZZZZZZZ :-)
Jeroen Wiert Pluimers

Mais um pensamento antes de fazer Zzzz: que tal fechar o tubo? Vou pensar sobre o que o melhor mecanismo de sinalização é para programonedizer a pipe, que é feito com\\.\pipe\foo
Jeroen Wiert Pluimers

@ Jeroen: Quando programoneterminar a saída dos dados, ele simplesmente fechará o arquivo de saída que estava usando. (Do lado do cliente, os pipes funcionam da mesma maneira que os arquivos comuns.) Quando isso ocorre, pipe.exe- mais precisamente pipe.CopyTo(...)- - alcançará o EOF e simplesmente sairá.
user1686

@ Jeroen: Além disso, há uma coisa que eu ainda não descobri: ao usar a ferramenta na outdireção oposta ( ) (copiar stdin para pipe), ela morre com o erro "Broken pipe" após os primeiros 1 kB. inPorém, não ocorre ao copiar um pipe para stdout ( ), portanto, não deve afetar o seu programa. (Como se costuma dizer, os patches são bem-vindos. )
user1686

Graças tentar isso mais tarde na próxima semana, algo no projeto veio com um prio superior (não que você ama projetos de TI <g>)
Jeroen Wiert Pluimers

4

Com base na resposta da grawity , criei uma versão estendida que permite que um processo seja iniciado diretamente sem a necessidade de usar várias janelas de terminal.

Uso geral:

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

A cadeia "{pipe}" é substituída pelo caminho de redirecionamento.

Exemplo do mundo real:

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

Essa linha de comandos pode ser inserida diretamente no Eclipse, por exemplo, para redirecionar o log de construção de um determinado construtor externo para o StdOut.

Este é provavelmente o melhor que obtém ...

Ligação

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.