Windows, как перенаправить параметр файла на стандартный вывод? (Windows эквивалент `` / dev / stdout`)


12

Консоль Windows:

  • Инструмент A может записывать двоичные данные в файл, но не имеет возможности указать ему использовать стандартный вывод.
  • Инструмент B может читать двоичные данные из stdin и обрабатывать информацию в нем.

Как я могу получить вывод от А по трубопроводу без использования промежуточного файла?

Другими словами: что является эквивалентом Windows /dev/stdout?

--jeroen

Ответы:


18

В Windows есть аналог для / dev / stdout, CON:

Я полагаю, что это все еще работает, учитывая продолжающуюся программу Microsoft "совместимость с прежними версиями".

Ах .. нашел это. Служба поддержки Microsoft предоставляет список зарезервированных имен. Вы не можете назвать файл этими именами, и они имеют особое значение, когда используются как входы или выходы.

Вы МОЖЕТЕ иметь возможность использовать CON в качестве устройства вывода для отправки на стандартный вывод.

Список:

   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
Спасибо, это действительно работает (даже в Win 8.1). Мы проводим сборку с Unity, в пакетном режиме: Unity.exe -batchmode -projectPath C:\***\Application -logFile -buildWebPlayer web -quit. Без аргумента (имя файла) -logFile- он должен печатать вывод на консоль, но это не так. После добавления CON (то есть - -logFile CON) - это делает :-)
Сетевой

@setevoy это на самом деле работает для вас с Unity на Windows? Вы можете дать более подробную информацию? Просто вызывает сбой Unity для меня на Windows 7 и 10 с использованием Unity.exe -batchmode -quit -projectPath "%cd%" -logFile CON -buildWindows64Player ".\GameBuild\Generic.exe". Команда работает нормально без файла журнала, но я не получаю вывод сборки.
bbodenmiller

@bbodenmiller Извините, но не могу предоставить больше информации - этот проект был завершен почти 2 года назад :-)
Сетевой

1
@bbodenmiller Кажется, что вывод файла журнала на стандартный вывод в данный момент прерван. См .: issetracker.unity3d.com/issues/…
Verox

2
Ответ неверный. CON устройство является дисплеем. Запись в CON не может быть ни перенаправлена ​​(как в program > file.txt), ни использована в канале (для передачи данных в stdin другой программы, как в program | another_program). Вывод, записанный в CON, всегда отображается. Правильный ответ: «У Windows нет эквивалента / dev / stdout»
Егор Скриптунов,

5

Windows не имеет прямого эквивалента /dev/stdout.


Вот моя попытка написать программу на C #, которая создает именованный канал , который может быть задан программе A как имя файла. Требуется .NET v4.

(C # потому что компилятор поставляется с .NET runtime, а какой компьютер не имеет .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

Например, используя .NET Client Profile v4.0.30319 в 32-битной Windows XP:

"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

@Jeroen: Когда programoneзакончится вывод данных, он просто закроет выходной файл, который использовал. (Со стороны клиента каналы работают так же, как и обычные файлы.) Когда это происходит, pipe.exeточнее говоря, pipe.CopyTo(...)достигнет EOF и просто завершится.
user1686

@Jeroen: Кроме того, есть одна вещь, которую я не понял: при использовании инструмента в противоположном outнаправлении () (копирование stdin в pipe) он умирает с ошибкой «Broken pipe» после первых 1 кБ. Однако этого не происходит при копировании канала в stdout ( in), поэтому это не должно влиять на вашу программу. (Как говорится, патчи приветствуются. )
user1686

спасибо, попробую это позже на следующей неделе, что-то в проекте получилось с более высоким приоритетом (разве вы не любите ИТ-проекты <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.

Это, наверное, лучшее, что он получает ...

Ссылка на сайт

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.