2008-09-19 39 views
5

Khi bạn ống hai quá trình và giết một tại "đầu ra" của đường ống, quá trình đầu tiên được sử dụng để nhận được tín hiệu "Broken Pipe", mà thường chấm dứt nó là tốt. Ví dụ. chạyỐng bị hỏng không còn kết thúc chương trình nữa?

$> do_something_intensive | less 

và sau đó thoát ít sử dụng để trả lại cho bạn ngay lập tức với một vỏ đáp ứng, trên một SuSE8 hoặc phiên bản cũ. khi tôi đang cố gắng hôm nay, do_something_intensive rõ ràng vẫn đang chạy cho đến khi tôi xóa thủ công. Có vẻ như một cái gì đó đã thay đổi (glib? Shell?) Khiến chương trình bỏ qua "các đường ống bị hỏng" ...

Bất kỳ ai trong các bạn đều có gợi ý về điều này? làm thế nào để khôi phục lại hành vi cũ? tại sao nó đã được thay đổi (hoặc tại sao nó luôn tồn tại nhiều ngữ nghĩa)?

chỉnh sửa: thử nghiệm thêm (sử dụng strace) cho thấy "SIGPIPE" được tạo ra, nhưng mà chương trình không bị gián đoạn. Một đơn giản

#include <stdio.h> 
int main() 
{ 
    while(1) printf("dumb test\n"); 
    exit(0); 
} 

sẽ tiếp tục với một bất tận

--- SIGPIPE (Broken pipe) @ 0 (0) --- 
write(1, "dumb test\ndumb test\ndumb test\ndu"..., 1024) = -1 EPIPE (Broken pipe) 

khi ít bị giết. Tôi có thể chắc chắn chương trình xử lý tín hiệu trong chương trình của tôi và đảm bảo nó chấm dứt, nhưng tôi đang tìm kiếm một số biến môi trường hoặc tùy chọn trình bao sẽ buộc các chương trình chấm dứt trên SIGPIPE

chỉnh sửa lại: có vẻ như là một vấn đề cụ thể tcsh (bash xử lý nó đúng) và phụ thuộc vào thiết bị đầu cuối (Eterm 0.9.4)

+0

Nó sẽ giúp bạn biết bạn đang sử dụng trình bao nào và cụ thể hơn về những gì do_something_intensive thực sự làm. Ngoài ra, bạn có ý nghĩa gì bởi "rõ ràng vẫn đang chạy"? Nó có hiển thị trong danh sách ps hay không, hoặc là shell không phản hồi? Vui lòng chỉnh sửa câu hỏi của bạn với nhiều chi tiết hơn! – ehdr

+0

nó xuất hiện trong một danh sách PS, sheel không đáp ứng cho đến khi tôi giết toàn bộ chuỗi với CTRL + C và sử dụng CPU được cao trong gkrellm. vỏ được sử dụng là tcsh, như được đề cập trong câu hỏi chi tiết hơn. cám ơn bạn đã góp ý. – PypeBros

Trả lời

0

Cám ơn lời khuyên của bạn, giải pháp là nhận được gần hơn ...

Theo manpage của tcsh, "vỏ không đăng nhập kế thừa chấm dứt hành vi của cha mẹ họ. Tín hiệu khác có giá trị mà vỏ thừa hưởng từ cha mẹ của nó. "

Đề xuất thiết bị đầu cuối thực sự là gốc của sự cố ... nếu nó bỏ qua SIGPIPE, chính vỏ cũng sẽ bỏ qua SIGPIPE ...

chỉnh sửa: tôi có xác nhận cuối cùng rằng sự cố chỉ phát sinh với Eterm + tcsh và tìm thấy tín hiệu bị thiếu đáng ngờ (SIGPIPE, SIG_DFL) trong mã nguồn Eterm. Tôi nghĩ rằng trường hợp gần.

+0

Tôi nhớ từ cách trở lại mà bỏ một vỏ csh với công việc backgrouynd cho phép các công việc để thực hiện trên chạy, nhưng bỏ một bash (ksh) vỏ sẽ giết bất kỳ công việc không nohup-ed. – dsm

+0

eterm/Eterm> svn diff Chỉ mục: src/command.c ================================== ================================= --- src/command.c (bản sửa đổi 40503) +++ src/command.c (bản sao làm việc) @@ -2304,6 +2304,7 @@ tín hiệu (SIGILL, SIG_DFL); tín hiệu (SIGSYS, SIG_DFL); tín hiệu (SIGALRM, SIG_DFL); + tín hiệu (SIGPIPE, SIG_DFL); #ifdef SIGTSTP tín hiệu (SIGTSTP, SIG_IGN); tín hiệu (SIGTTIN, SIG_IGN); – PypeBros

8

Vâng, nếu có một nỗ lực để ghi vào một đường ống sau khi người đọc đã biến mất, một tín hiệu SIGPIPE được tạo ra . Ứng dụng này có khả năng bắt tín hiệu này, nhưng nếu không, quá trình này sẽ bị giết.

SIGPIPE sẽ không được tạo cho đến khi quá trình gọi cố gắng ghi, vì vậy nếu không có thêm đầu ra, nó sẽ không được tạo.

2

Đã "làm điều gì đó chuyên sâu" đã thay đổi chưa?

Như Daniel đã đề cập SIGPIPE không phải là một tín hiệu "đường ống của bạn đi" ma thuật mà là một tín hiệu "thử tốt, bạn không còn có thể đọc/ghi ống" nữa.

Nếu bạn có quyền kiểm soát "làm điều gì đó chuyên sâu", bạn có thể thay đổi nó để viết ra một số "tiến trình chỉ báo" đầu ra khi nó quay. Điều này sẽ nâng cao SIGPIPE một cách kịp thời.

+0

về do_something_intensive: nếu tôi đang thực hiện "có | ít" và chấm dứt 'ít hơn', "có" nhận SIGPIPE và chấm dứt. nếu thay vào đó tôi đang làm "objdump -drS ... | less", "objdump" tiếp tục (mặc dù strace tiết lộ SIGPIPEs gặt hái được); do đó, không một vòng lặp câm làm "printf". – PypeBros

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