2010-10-29 43 views
8

Tôi đã viết một mã để nhận được một lỗi runtime cố ý:Về stdout/stderr chuyển hướng

int main() 
{ 
int a=5; 
printf("Hello World\n"); 
printf("a=%s\n", a); 
} 

Nó cung cấp cho:

$ ./error.o 
Hello World 
Segmentation Fault 
$ 

Bây giờ, để ghi lại các lỗi thời gian chạy, tôi làm:

$ ./error.o > so.txt 
$ ./error.o &> soe.txt 

Nhưng cả hai tệp đều trống. Tại sao?

EDIT:

Tôi thực sự viết một tập lệnh để biên dịch từ xa và thực thi chương trình c. Từ các câu trả lời tôi nhận được rằng Segmentation Fault không phải là đầu ra lỗi của chương trình. Vậy, có cách nào để nắm bắt đầu ra đó không? Ngoài ra, chương trình chỉ là một mẫu, vì vậy tôi không thể thêm các câu lệnh. Có thể làm đệm đường được thực hiện theo bất kỳ cách nào khác với chuyển hướng không?

+0

% s cho int là sai. – Nyan

+0

@Nyan: Tôi đang cố ý để có được lỗi seg. Tôi đang viết một kịch bản để nắm bắt các lỗi thực hiện, do đó, điều này chỉ bắt chước đầu vào có thể trong tương lai đối với tập lệnh của tôi. – lalli

+1

Bạn đã chỉnh sửa câu hỏi về cách bật tính năng đệm đường cho các tệp được chuyển hướng. Tôi đã cập nhật câu trả lời của mình để thêm thông tin. – jjrv

Trả lời

10

so.txt trống vì stdout không bị xóa trước khi xảy ra sự cố nên nội dung đệm đã bị mất. Nếu bạn thêm: fflush (stdout); giữa các lệnh printf, nó sẽ chứa văn bản mong muốn.

Soe.txt của bạn bị thiếu cũng là thông báo "Phân đoạn lỗi" vì nó được in bởi trình bao, chứ không phải bởi chương trình của bạn và do đó không phải là một phần của đầu ra của chương trình được chuyển hướng.

Nếu bạn không thể sửa đổi mã, bạn có thể bật bộ đệm đường bằng cách đánh lừa chương trình để nghĩ rằng nó đang in thành một tty. Tạo kịch bản error.sh:

#!/bin/sh 
./error.o 

Sau đó làm chmod a + x error.sh và gọi nó là như thế này trên Linux:

script soe.txt -c ./error.sh 

Hoặc như thế này trên OS X:

script soe.txt ./error.sh 

Đầu ra chính xác có phần phụ thuộc vào hệ thống nhưng có thể chứa cả "Hello World" và "Fault Segmentation".

Đồng thời xem xét thêm các dòng #include thích hợp và trả về giá trị từ chính.

+0

có cách nào để nắm bắt 'Lỗi phân đoạn' trong tệp không? tôi có thể chạy một bash bên trong bash và làm như vậy không? – lalli

+0

Có, câu trả lời đã được cập nhật. – jjrv

+0

ah, cảm ơn ..... – lalli

7

Vì lỗi phân đoạn là nghiêm trọng. Bộ đệm không bị đỏ bừng, quá trình của bạn chỉ bị đóng xuống dữ dội.

Lý do bạn thấy văn bản khi bạn chạy mà không chuyển hướng là đầu ra tiêu chuẩn là bộ đệm dòng (ISO C yêu cầu bộ đệm đầy đủ chỉ được sử dụng nếu thiết bị có thể được xác định là không tương tác). Nói cách khác, nó sẽ tuôn ra bất cứ khi nào nó thấy một dòng mới, và điều đó xảy ra trước khi tham chiếu không hợp lệ của bạn.

Nhưng vì đầu ra tệp không được đệm theo dòng, thông tin vẫn đang chờ để được gửi đi khi vũ trụ chương trình của bạn được kéo ra từ dưới nó.

Mặc dù hỗ trợ cho điều này là thực hiện xác định, bạn có thể đặt một tay cầm tập tin cụ thể dòng đệm bằng cách sử dụng setvbuf với chế độ _IOLBF, một cái gì đó như:

setvbuf (stdin, NULL, _IOLBF, BUFSIZ); 

vào đầu main() - nó tiết kiệm một số lượng đáng kể việc gõ trên phải fflush mọi dòng đầu ra.

+0

là có một cách để đệm các dòng với các chuyển hướng? – lalli

+0

cảm ơn, đoán tôi phải đánh lừa lịch trình sau đó ... – lalli

+0

@ lalli, có bạn có thể, tôi đã thường làm điều này để tránh phải đặt 'fflush()' ở khắp mọi nơi. Xem bản cập nhật trên 'setvbuf()'. – paxdiablo

3

Tôi nghĩ rằng điều này sẽ làm điều đó:

echo ./error.o | sh > error.txt 
+0

oh, điều này giúp, cảm ơn .. – lalli