Я не впевнений, чому ви не хочете перенаправляти файл. Існують два способи, які я наведу тут. Один з методів полягає в тому, щоб перенаправляти файл і читати з нього, інший - це набір програм.
Названі труби
Те, що я зробив, було написання двох програм для .NET 4. Один надсилає вивід на іменовану трубку, інший читає з цієї труби і виводить на консоль. Використання досить просте:
asdf.exe | NamedPipeServer.exe "APipeName"
В іншому вікні консолі:
NamedPipeClient.exe "APipeName"
На жаль, це може лише перенаправити stdout
(або stdin
або комбіновано) stderr
самостійно, через обмеження в операторі труби ( |
) у командному рядку Windows. Якщо ви зрозумієте, як відправити stderr
через цього оператора труби він повинен працювати. Крім того, сервер може бути змінений, щоб запустити вашу програму та спеціально перенаправити stderr
. Якщо це необхідно, дайте мені знати в коментарі (або зробіть це самостійно); це не надто складно, якщо ви маєте знання бібліотеки C # та .NET "Процес".
Ви можете завантажити сервер і клієнта .
Якщо закрити сервер після з'єднання, клієнт негайно закриється. Якщо ви закриєте клієнт після з'єднання, сервер закриється, як тільки ви спробуєте щось надіслати через нього. Неможливо повторно підключити розбиту трубку, головним чином тому, що я не можу турбуватися про те, що зараз так складно. Це також обмежено один клієнт на сервер .
Вихідний код
Вони написані на 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
- Створіть порожній файл
- Запустіть нове вікно консолі, яке слідкує за файлом
- Виконати виконуваний файл і перенаправити
stderr
Вивести цей файл
Це забезпечує бажаний ефект перегляду одного вікна консолі stdout
(і надавати stdin
), а інший дивитися stderr
.
Все, що імітує tail
буде працювати. Метод PowerShell працює у Windows, але може бути трохи повільним (тобто існує деяка затримка між записом до файлу та відображенням на екран). Подивитися це питання StackOverflow для інших tail
альтернатив.
Єдина проблема - тимчасовий файл може стати досить великим. Можливим обхідним шляхом є запуск циклу, який друкується, лише якщо файл має вміст і очищає файл відразу після цього, але це може спричинити стан гонки.