Windows如何将文件参数重定向到stdout?(Windows等同于`/ dev / stdout`)


12

Windows控制台:

  • 工具A可以将二进制数据写入文件,但是没有选择告诉它使用stdout的选项。
  • 工具B可以从stdin读取二进制数据并处理其中的信息。

如何在不使用中间文件的情况下从A通过B获得输出?

换句话说:Windows等效于/dev/stdout什么?

--jeroen

Answers:


19

Windows确实有一个/ dev / stdout的类似物,CON:

考虑到Microsoft正在进行的“旧版兼容性”计划,我认为它仍然可以工作。

啊..找到了。 Microsoft支持提供了保留名称的列表。您不能使用这些名称来命名文件,它们在用作输入或输出时具有特殊含义。

您可能可以将CON用作输出设备以发送到stdout。

名单:

   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

2
谢谢,它确实有效(即使在Win 8.1中也是如此)。我们使用Unity以批处理模式运行build Unity.exe -batchmode -projectPath C:\***\Application -logFile -buildWebPlayer web -quit。不带参数(文件名)的-logFile-必须将输出打印到控制台,但不是。添加CON(即- -logFile CON)之后-: ))
setevoy

@setevoy这实际上适用于Windows上的Unity吗?您能提供更多细节吗?使用Windows在Windows 7和10上导致Unity崩溃Unity.exe -batchmode -quit -projectPath "%cd%" -logFile CON -buildWindows64Player ".\GameBuild\Generic.exe"。没有日志文件,命令运行正常,但没有生成输出。
bbodenmiller

@bbodenmiller对不起,但无法提供更多信息-该项目大约在两年前完成:-)
setevoy

1
@bbodenmiller似乎将日志文件输出到stdout的操作目前已中断。请参阅:issuetracker.unity3d.com/issues/…–
Verox

2
答案是错误的。显示CON设备。写入CON既不能重定向(如program > file.txt),也不能在管道中使用(将数据传递到)中的另一个程序的stdin中program | another_program。写入CON的输出始终显示。正确的答案是“ Windows没有等效的/ dev / stdout”
Egor Skriptunoff

5

Windows没有直接等效于/dev/stdout


这是我编写C#程序的尝试,该程序创建一个命名管道,可以将其作为文件名提供给程序A。需要.NET v4。

(C#是因为编译器随.NET运行时一起提供的,并且最近哪些计算机没有.NET?)

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

编译:

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

csc 可以在 %SystemRoot%\Microsoft.NET\Framework64\<version>\csc.exe

例如,在32位Windows XP上使用.NET Client Profile v4.0.30319:

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

跑:

PipeServer foo in | programtwo

在第一个窗口中,然后:

programone \\.\pipe\foo

在第二个窗口中。


+1现在是一个很酷的解决方案!我会尽快尝试,并告诉您。现在先介绍一些Zzzzzzz :-)
Jeroen Wiert Pluimers

在做Zzzz之前再想一想:关闭管道怎么办?我要考虑最好的信号传递机制是programone什么pipe,它可以完成\\.\pipe\foo
Jeroen Wiert Pluimers,2011年

@Jeroen:programone完成数据输出后,它将仅关闭其使用的输出文件。(从客户端来看,管道的工作方式与普通文件相同。)这样做的话pipe.exe-更准确地说pipe.CopyTo(...)-将到达EOF并直接退出。
user1686

@Jeroen:另外,我还没有发现一件事:在相反(out)方向上使用该工具(将stdin复制到管道中)时,在第一个1 kB之后它死于“ Broken pipe”错误。in但是,将管道复制到stdout()时不会发生,因此不会影响您的程序。(正如他们所说,欢迎打补丁。
2011年

感谢您将在下周晚些时候尝试此操作,该项目中的某些问题会带来更高的优先级(您是否不喜欢IT项目<g>)
Jeroen Wiert Pluimers

4

基于grawity的答案,我创建了扩展版本,该版本允许无需使用多个终端窗口即可直接启动进程。

一般用法:

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

然后,将字符串“ {pipe}”替换为重定向路径。

真实示例:

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

例如,可以将该命令行直接插入Eclipse,以将某个外部构建器的构建日志重定向到StdOut。

这可能是最好的...

链接

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.