2008-11-19 38 views
7

Làm cách nào để khởi chạy ứng dụng và nắm bắt đầu ra thông qua thiết bị xuất chuẩn và có thể là tiêu chuẩn?khởi chạy ứng dụng, chụp stdout và stderr bằng C++

Tôi đang viết một hệ thống xây dựng tự động và tôi cần nắm bắt đầu ra để phân tích. Tôi muốn cập nhật repo svn và lấy số sửa đổi để tôi có thể di chuyển các tập tin trong autobuild/revNumber/nếu thành công. Tôi cũng muốn xây dựng bằng cách sử dụng tạo và tải lên văn bản biên dịch cho máy chủ của tôi để mọi người xem các cảnh báo và lỗi trên bản dựng không thành công.

Tôi không thể tìm thấy hàm system(), nhưng tôi đã tìm thấy hàm CreateProcess() trên MSDN. Tôi có thể khởi động những gì tôi cần nhưng tôi không có ý tưởng làm thế nào để nắm bắt stderr và stdout. Tôi nhận thấy quá trình này khởi chạy riêng biệt trừ khi tôi đặt điểm ngắt và giữ ứng dụng của tôi thoát mà sau đó nó sẽ giữ tất cả văn bản trong cửa sổ bảng điều khiển ứng dụng của tôi. Tôi cũng muốn đợi cho đến khi tất cả các quy trình được hoàn thành và sau đó quét dữ liệu mà nó tạo ra để thực hiện bất kỳ thao tác bổ sung nào mà tôi cần. Làm thế nào để tôi làm được điều này?

Trả lời

11

Trong vỏ thực (có nghĩa là, không vỏ sò biển - Ý tôi là, không phải trong C Shell hoặc các dẫn xuất của nó), sau đó:

program arg1 arg2 >/tmp/log.file 2>&1 

này chạy chương trình với các đối số được đưa ra, và chuyển hướng stdout để/tmp /log.file; ký hiệu ( chữ tượng hình) '2>&1' ở cuối gửi stderr (bộ mô tả tập tin 2) đến cùng một vị trí mà stdout (bộ mô tả tập tin 1) đang diễn ra. Lưu ý rằng chuỗi hoạt động là quan trọng; nếu bạn đảo ngược chúng, thì lỗi chuẩn sẽ đi đến nơi đầu ra tiêu chuẩn đang đi, và sau đó đầu ra tiêu chuẩn (nhưng không phải lỗi chuẩn) sẽ được chuyển hướng đến tệp.

Việc lựa chọn tên tệp được hiển thị là vô lý vì nhiều lý do - bạn nên cho phép người dùng chọn thư mục và có thể bao gồm ID tiến trình hoặc dấu thời gian trong tên tệp.

LOG=${TMPDIR:-/tmp}/log.$$.$(date +%Y%m%d-%H%M%S) 
program arg1 arg2 >$LOG 2>&1 

Trong C++, bạn có thể sử dụng chức năng system() (được kế thừa từ C) để chạy quy trình. Nếu bạn cần biết tên tệp trong chương trình C++ (chính đáng), thì hãy tạo tên trong chương trình (strftime() là bạn của bạn) và tạo chuỗi lệnh với tên tệp đó. (Nghiêm túc, bạn cũng cần getenv() để nhận được $ TMPDIR và hàm POSIX getpid() để lấy ID tiến trình và sau đó bạn có thể mô phỏng tập lệnh shell hai dòng (mặc dù PID được sử dụng sẽ là của chương trình C++ chứ không phải Thay vào đó, bạn có thể sử dụng chức năng POSIX popen(), bạn phải bao gồm ký hiệu '2>&1' trong chuỗi lệnh mà bạn tạo để gửi lỗi chuẩn của lệnh đến cùng một vị trí như đầu ra tiêu chuẩn , nhưng bạn sẽ không cần một tệp tạm thời:

Sau đó, bạn có thể đọc luồng tệp. cách sạch để ánh xạ một luồng tập tin C thành một dòng C++; có lẽ là vậy.

+0

Tôi tin rằng tên của ký tự "&"/glyph là ký hiệu &. –

+0

Đồng ý: nhưng tôi đã đề cập đến tất cả các '2> & 1' là 'chữ tượng hình' (trong đó, tôi sẽ sẵn sàng cấp, là một sự lạm dụng thuật ngữ này). –

+0

Tôi nghĩ rằng sẽ rõ ràng hơn một chút nếu bạn gọi '2> & 1' là 'chuyển hướng' thay vì 'heiroglyph'. Một người không quen thuộc với ngôn ngữ học Ai Cập và đi và tìm kiếm các thuật ngữ trên wikipedia có thể trở nên rất bối rối. :) –

4

Bạn cần điền vào cấu trúc STARTUP_INFO, có hStdInput, hStdOutput và hStdError. Hãy nhớ kế thừa các xử lý khi bạn CreateProcess.

/* Assume you open a file handle or pipe called myoutput */ 
STARTUP_INFO si_startinfo; 
ZeroMemory(&si_startinfo, sizeof(STARTUP_INFO)); 
si_startinfo.cb = sizeof(STARTUP_INFO); 
si_startinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); 
si_startinfo.hStdOutput = myoutput; 
si_startinfo.hStdError = myoutput; 
si_startifno.dwFlags != STARTF_USEHANDLES; 

PROCESS_INFORMATION pi_procinfo; 
ZeroMemory(&pi_procinfo, sizeof(PROCESS_INFORMATION); 

CreateProcess(NULL, cmdline, NULL, NULL, true, 0, NULL, pathname, &si_startinfo, &pi_procinfo); 

Tôi chưa hiển thị các khía cạnh xử lý lỗi mà bạn cần phải làm. Đối số thứ 5 được đặt thành true để kế thừa các điều khiển. Những người khác đã giải thích làm thế nào để tạo ra đường ống vì vậy tôi sẽ không lặp lại nó ở đây.

0

CRT của Microsoft và thư viện MSDN bao gồm chức năng hệ thống và chức năng _popen.

Các vấn đề liên quan