n61*_*007 23 windows redirection command-line pipe named-pipe
有没有办法将Win32 控制台中进程的标准输出重定向到命名管道?命名管道内置于 Windows 中,虽然它们是一个有用的概念,但我从未见过它们从命令行使用。
IE。喜欢example.exe >\\.\mypipe。(此语法可能不正确,但您明白了。)我希望能够同时将stdout和stderr重定向到不同的管道。
我想避免使用物理文件作为替代,以避免处理 IO 缓慢、IO 缓冲区、文件锁、访问权限、可用硬盘空间、决定覆盖、无意义的持久性等。
另一个原因是因为传统的 Windows工具集不像在 Unix 中那样围绕基于(文本)文件的哲学设计。此外,命名管道不能轻易安装在 Windows 中,如果有的话。
最后,好奇一个好的概念是否可以得到很好的使用。
IS4*_*IS4 27
我很惊讶这还没有得到正确回答。确实有一个由系统分配给命名管道的UNC 路径,可以在网络中的任何机器上访问,可以像普通文件一样使用:
program.exe >\\.\pipe\StdOutPipe 2>\\.\pipe\StdErrPipe
Run Code Online (Sandbox Code Playgroud)
假设这台机器上存在名为“StdOutPipe”和“StdErrPipe”的管道,这将尝试连接并写入它们。该pipe部分是指定您需要命名管道的部分。
Bob*_*Bob 10
我不确定您为什么不想重定向到文件。我将在这里提供两种方法。一种方法是重定向到文件并从中读取,另一种方法是一组程序。
我所做的是为 .NET 4 编写两个程序。一个将输出发送到命名管道,另一个从该管道读取并显示到控制台。用法很简单:
asdf.exe | NamedPipeServer.exe "APipeName"
Run Code Online (Sandbox Code Playgroud)
在另一个控制台窗口中:
NamedPipeClient.exe "APipeName"
Run Code Online (Sandbox Code Playgroud)
不幸的是,由于Windows 命令提示符中管道运算符 ( ) 的限制,这只能重定向stdout(或stdin,或组合),而不能单独重定向。如果您弄清楚如何通过该管道操作员发送,它应该可以工作。或者,可以修改服务器以启动您的程序并专门重定向. 如果有必要,请在评论中告诉我(或自己做);如果您有一些 C# 和 .NET“进程”库知识,这并不太难。stderr|stderrstderr
如果在连接后关闭服务器,客户端将立即关闭。如果您在连接后关闭客户端,服务器将在您尝试通过它发送内容时立即关闭。重新连接损坏的管道是不可能的,主要是因为我现在懒得做这么复杂的事情。它也仅限于每个服务器一个客户端。
这些是用 C# 编写的。试图解释它没有多大意义。他们使用 .NET NamedPipeServerStream和NamedPipeClientStream。
服务器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
namespace NamedPipeServer
{
class Program
{
static void Main(string[] args)
{
if (args == null || args.Length == 0)
{
Console.Error.WriteLine("[NamedPipeServer]: Need pipe name.");
return;
}
NamedPipeServerStream PipeServer = new NamedPipeServerStream(args[0], System.IO.Pipes.PipeDirection.Out);
PipeServer.WaitForConnection();
StreamWriter PipeWriter = new StreamWriter(PipeServer);
PipeWriter.AutoFlush = true;
string tempWrite;
while ((tempWrite = Console.ReadLine()) != null)
{
try
{
PipeWriter.WriteLine(tempWrite);
}
catch (IOException ex)
{
if (ex.Message == "Pipe is broken.")
{
Console.Error.WriteLine("[NamedPipeServer]: NamedPipeClient was closed, exiting");
return;
}
}
}
PipeWriter.Close();
PipeServer.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
客户端:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
namespace NamedPipeClient
{
class Program
{
static void Main(string[] args)
{
if (args == null || args.Length == 0)
{
Console.Error.WriteLine("[NamedPipeClient]: Need pipe name.");
return;
}
NamedPipeClientStream PipeClient = new NamedPipeClientStream(".", args[0], System.IO.Pipes.PipeDirection.In);
PipeClient.Connect();
StreamReader PipeReader = new StreamReader(PipeClient);
string tempRead;
while ((tempRead = PipeReader.ReadLine()) != null)
{
Console.WriteLine(tempRead);
}
PipeReader.Close();
PipeClient.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
type NUL>StdErr.temp
start powershell -c Get-Content StdErr.temp -Wait
MyExecutable.exe 2>StdErr.temp
Run Code Online (Sandbox Code Playgroud)
stderr输出重定向到该文件这提供了一个控制台窗口观看stdout(并提供stdin)和另一个观看的预期效果stderr。
任何模仿的东西tail都会起作用。PowerShell 方法本机在 Windows 中工作,但可能有点慢(即在写入文件和显示到屏幕之间存在一些延迟)。有关其他替代方案,请参阅此 StackOverflow 问题tail。
唯一的问题是临时文件可能会变得非常大。一种可能的解决方法是运行一个循环,仅在文件有内容时才打印并在之后立即清除文件,但这会导致竞争条件。
| 归档时间: |
|
| 查看次数: |
33600 次 |
| 最近记录: |