Windows làm thế nào để chuyển hướng tham số tệp đến thiết bị xuất chuẩn? (Tương đương với Windows của `/ dev / stdout`)


12

Bảng điều khiển Windows:

  • Công cụ A có thể ghi dữ liệu nhị phân vào một tệp, nhưng không có tùy chọn nào để bảo nó sử dụng thiết bị xuất chuẩn.
  • Công cụ B có thể đọc dữ liệu nhị phân từ stdin và xử lý thông tin trong đó.

Làm cách nào tôi có thể nhận đầu ra từ A được dẫn qua B mà không cần sử dụng tệp trung gian?

Nói cách khác: Windows tương đương với /dev/stdoutcái gì?

--jeroen

Câu trả lời:


18

Windows không có tương tự cho / dev / stdout, CON:

Tôi tưởng tượng nó vẫn hoạt động, xem xét chương trình "tương thích di sản" đang diễn ra của Microsoft.

À .. tìm thấy rồi. Hỗ trợ của Microsoft đưa ra một danh sách các tên dành riêng. Bạn không thể đặt tên cho một tệp là những tên này và chúng có ý nghĩa đặc biệt khi được sử dụng làm đầu vào hoặc đầu ra.

Bạn MIGHT có thể sử dụng CON làm thiết bị đầu ra để gửi đến thiết bị xuất chuẩn.

Danh sách:

   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
Cảm ơn, nó thực sự hoạt động (ngay cả trong Win 8.1). Chúng tôi chạy bản dựng với Unity, trong chế độ hàng loạt : Unity.exe -batchmode -projectPath C:\***\Application -logFile -buildWebPlayer web -quit. Không có đối số (tên tệp) thành -logFile- nó phải in đầu ra ra bàn điều khiển, nhưng không được. Sau khi thêm CON (tức là - -logFile CON) - nó thực hiện :-)
setevoy

@setevoy cái này thực sự hiệu quả với bạn với Unity trên Windows? Bạn có thể cho biết thêm chi tiết? Chỉ gây ra sự cố Unity cho tôi trên Windows 7 và 10 khi sử dụng Unity.exe -batchmode -quit -projectPath "%cd%" -logFile CON -buildWindows64Player ".\GameBuild\Generic.exe". Lệnh hoạt động tốt mà không cần tệp nhật ký nhưng tôi không nhận được đầu ra xây dựng.
bbodenmiller

@bbodenmiller Xin lỗi, nhưng không thể cung cấp thêm thông tin - dự án này đã hoàn thành gần 2 năm trước :-)
setevoy 11/03/2017

1
@bbodenmiller Có vẻ như việc đưa logfile vào thiết bị xuất chuẩn bị hỏng tại thời điểm này. Xem: suetracker.unity3d.com/issues/ từ
Verox

2
Câu trả lời là sai. Thiết bị CON được hiển thị. Viết thư cho CON có thể không được chuyển hướng (như trong program > file.txt) cũng như không được sử dụng trong một đường ống (để truyền dữ liệu đến stdin của chương trình khác như trong program | another_program). Đầu ra được ghi vào CON luôn hiển thị. Câu trả lời đúng là "Windows không có tương đương với / dev / stdout"
Egor Skriptunoff

5

Windows không có tương đương trực tiếp với /dev/stdout.


Đây là nỗ lực của tôi trong việc viết chương trình C # tạo ra một ống có tên , có thể được trao cho chương trình A dưới dạng tên tệp. Yêu cầu .NET v4.

(C # vì trình biên dịch đi kèm với thời gian chạy .NET và những gì máy tính không có .NET ngày nay?)

TubeServer.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);
        }
    }
}

Biên dịch với:

csc PipeServer.cs /r:System.Core.dll

csc Có thể được tìm thấy trong %SystemRoot%\Microsoft.NET\Framework64\<version>\csc.exe

Ví dụ: sử dụng .NET Client Profile v4.0.30319 trên Windows XP 32 bit:

"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\csc.exe" PipeServer.cs /r:System.Core.dll

Chạy:

PipeServer foo in | programtwo

trong cửa sổ một, và:

programone \\.\pipe\foo

trong cửa sổ hai.


+1 Bây giờ đó là một giải pháp tuyệt vời! Tôi sẽ thử điều đó sớm và cho bạn biết. Bây giờ đầu tiên một số Zzzzzzz :-)
Jeroen Wiert Pluimers

Thêm một suy nghĩ trước khi làm Zzzz: còn việc đóng ống thì sao? Tôi sẽ suy nghĩ về cơ chế báo hiệu tốt nhất programoneđể nói là gì pipe, nó được thực hiện với\\.\pipe\foo
Jeroen Wiert Pluimers

@Jeroen: Khi programonehoàn thành xuất dữ liệu, nó sẽ chỉ đóng tệp đầu ra mà nó đang sử dụng. (Từ phía máy khách, các đường ống hoạt động giống như các tệp thông thường.) Khi làm như vậy, pipe.exe- chính xác hơn, pipe.CopyTo(...)- sẽ đạt EOF và chỉ cần thoát.
dùng1686

@Jeroen: Ngoài ra, có một điều tôi chưa tìm ra: khi sử dụng công cụ theo hướng ngược lại ( out) (sao chép stdin sang đường ống), nó sẽ chết với lỗi "Broken pipe" sau 1 kB đầu tiên. inTuy nhiên, điều đó không xảy ra khi sao chép một đường ống vào thiết bị xuất chuẩn ( ), vì vậy nó không ảnh hưởng đến chương trình của bạn. (Như họ nói, các bản vá được chào đón. )
user1686

cảm ơn sẽ thử điều này vào cuối tuần tới, một cái gì đó trong dự án đã xuất hiện với một ưu tiên cao hơn (bạn không thích các dự án CNTT <g>)
Jeroen Wiert Pluimers

4

Dựa trên câu trả lời của grawity Tôi đã tạo một phiên bản mở rộng cho phép một quá trình được bắt đầu trực tiếp mà không phải sử dụng nhiều cửa sổ đầu cuối.

Sử dụng chung:

PipeServer [in|out] [process name] [argument 1] [argument 2] [...]

Chuỗi "{pipe}" sau đó được thay thế bằng đường dẫn chuyển hướng.

Ví dụ thực tế:

PipeServer.exe in "C:\Keil\UV4\Uv4.exe" -b "C:\Project\Project.uvproj" -j0 -o "{pipe}"

Dòng lệnh này có thể được chèn trực tiếp vào, ví dụ, Eclipse để chuyển hướng nhật ký xây dựng của một trình xây dựng bên ngoài nhất định đến StdOut.

Đây có lẽ là thứ tốt nhất mà nó có được ...

Liên kết

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.