Windows, як перенаправити параметр файлу на stdout? (Windows еквівалент `/ dev / stdout`)


13

Консоль Windows:

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

Як я можу отримати вихід з "А" через B, не використовуючи проміжний файл?

Іншими словами: що таке еквівалент Windows /dev/stdout?

--jeroen

Відповіді:


20

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

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

@bbodenmiller Вибачте, але не можу надати більше інформації - цей проект був закінчений майже 2 роки тому :-)
setevoy

1
@bbodenmiller Начебто виведення лог-файлу в stdout наразі порушено. Дивіться: issueetracker.unity3d.com/isissue/…
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

Наприклад, за допомогою .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 та просто вийде.
користувач1686

@Jeroen: Крім того, є ще одне, чого я не з'ясував: коли використовується інструмент у зворотному ( out) напрямку (скопіюйте stdin у трубу), він вмирає з помилкою "Розбита труба" після перших 1 кБ. inОднак цього не відбувається при копіюванні труби в stdout ( ), тому це не повинно впливати на вашу програму. (Як то кажуть, латки вітаються. )
користувач1686

дякую спробую це пізніше наступного тижня, щось у проекті придумало вищий пріоритет (чи не любиш ти ІТ-проекти <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.