Windows에서 stdout을 명령줄의 (명명된) 파이프로 리디렉션할 수 있나요?

Windows에서 stdout을 명령줄의 (명명된) 파이프로 리디렉션할 수 있나요?

리디렉션하는 방법이 있나요?표준 출력프로세스의Win32 콘솔에게명명된 파이프? 명명된 파이프는 Windows에 내장되어 있으며 유용한 개념이기는 하지만 명령줄에서 사용되는 것을 본 적이 없습니다.

즉. 좋다 example.exe >\\.\mypipe. (이 구문은 정확하지 않을 수 있지만 요점은 알 수 있습니다.) 리디렉션할 수 있기를 바랍니다.표준 출력그리고표준 오류동시에 다른 파이프에.

IO 속도 저하, IO 버퍼, 파일 잠금, 액세스 권한, 사용 가능한 하드 디스크 공간, 덮어쓰기 결정, 의도하지 않은 지속성 등의 문제를 피하기 위해 물리적 파일을 대체물로 사용하는 것을 피하고 싶습니다.

또 다른 이유는 전통적인 Windows도구 세트(텍스트) 파일 기반 철학을 중심으로 설계되지 않았습니다.유닉스에서와 마찬가지로. 또한 명명된 파이프는 Windows에 쉽게 마운트될 수 없습니다.

마지막으로, 좋은 컨셉이 잘 활용될 수 있을지 궁금합니다.

답변1

왜 파일로 리디렉션하고 싶지 않은지 잘 모르겠습니다. 여기서는 두 가지 방법을 제공하겠습니다. 한 가지 방법은 파일로 리디렉션하고 읽는 것이고, 다른 방법은 일련의 프로그램을 사용하는 것입니다.


명명된 파이프

내가 한 일은 .NET 4용 프로그램 두 개를 작성하는 것이었습니다. 하나는 명명된 파이프로 출력을 보내고, 다른 하나는 이 파이프에서 읽고 콘솔에 표시합니다. 사용법은 매우 간단합니다.

asdf.exe | NamedPipeServer.exe "APipeName"

다른 콘솔 창에서:

NamedPipeClient.exe "APipeName"

불행하게도 이것은 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();
        }
    }
}

클라이언트:

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

파일로 리디렉션

type NUL>StdErr.temp
start powershell -c Get-Content StdErr.temp -Wait
MyExecutable.exe 2>StdErr.temp
  1. 빈 파일 만들기
  2. 파일을 감시하는 새 콘솔 창을 시작합니다.
  3. 실행 파일을 실행하고 stderr출력을 해당 파일로 리디렉션

이는 하나의 콘솔 창에서 감시 stdout(및 제공 stdin)하고 다른 콘솔 창에서 감시하는 원하는 효과를 제공합니다 stderr.

흉내내는 것은 무엇 tail이든 작동할 것입니다. PowerShell 방법은 기본적으로 Windows에서 작동하지만 약간 느릴 수 있습니다(즉, 파일 쓰기와 화면 표시 사이에 약간의 대기 시간이 있음). 보다이 StackOverflow 질문다른 대안을 위해 tail.

유일한 문제는 임시 파일이 상당히 커질 수 있다는 것입니다. 가능한 해결 방법은 파일에 내용이 있는 경우에만 인쇄하고 그 후 즉시 파일을 지우는 루프를 실행하는 것입니다. 그러나 이로 인해 경쟁 조건이 발생할 수 있습니다.

답변2

나는 이것이 이미 올바르게 답변되지 않았다는 사실에 놀랐습니다. 실제로UNC 경로시스템에 의해 명명된 파이프에 할당되고 네트워크의 모든 컴퓨터에서 액세스할 수 있으며 일반 파일처럼 사용할 수 있습니다.

program.exe >\\.\pipe\StdOutPipe 2>\\.\pipe\StdErrPipe

"StdOutPipe" 및 "StdErrPipe"라는 파이프가 이 시스템에 존재한다고 가정하면 연결 및 쓰기가 시도됩니다. 부분 pipe은 명명된 파이프를 원함을 지정하는 것입니다.

답변3

서버에서 클라이언트 dos 창으로의 Windows 데이터 파이프에 대한 기본 설정은 즉시 또는 나중에 작은 RAM 드라이브로 충족될 수 있습니다. 파일 시스템과 같은 이름으로 쓰거나 읽은 데이터에 대해 동일한 메모리가 할당됩니다. 클라이언트는 다 사용한 파일을 삭제하고 다른 파일을 기다리거나 컴퓨터가 종료될 때 사라지도록 둡니다.

관련 정보