Lỗi phân đoạn tin nhắn (bị đổ lõi), được phát ra bởi bash, không phải do chương trình bị sập (khi tin nhắn được phát ra, chương trình đã chết!). Việc chuyển hướng chỉ áp dụng cho chính chương trình.
Để chuyển hướng các thông điệp từ chính shell về chương trình, hãy chạy chương trình bên trong cấu trúc nhóm shell và chuyển hướng đầu ra của cả nhóm. Cấu trúc nhóm vỏ cơ bản nhất, không có gì ngoài nhóm, là niềng răng.
ret=`{ ./segfault; } 2>&1`
Biểu mẫu ret=`eval ./segfault 2>&1`
áp dụng chuyển hướng cho toàn bộ đánh giá eval
lệnh, vì vậy về nguyên tắc, nó sẽ hoạt động và trên thực tế nó hoạt động trên máy của tôi với bash 4.3.30 và các phiên bản cũ hơn. Điều có thể xảy ra (và tôi có thể sao chép nó bằng ksh) là phiên bản bash của bạn thực hiện một số tối ưu hóa để tránh bỏ các chương trình con khi chúng là lệnh cuối cùng trong một lớp con. Cách danh nghĩa để thực thi lệnh ret=`eval ./segfault`
là:
- Tạo một đường ống.
- Fork, tức là tạo một quy trình con shell. Trong quy trình con (quy trình 1):
- Chuyển hướng đầu ra vào đường ống.
- Thi công
eval
dựng sẵn.
- Cái nĩa. Trong quy trình con (quy trình 2):
- Thực thi tệp
./segfault
, tức là thay thế chương trình shell hiện đang chạy trong quy trình này segfault
.
- (Trong quy trình 1) Đợi quá trình 2 kết thúc.
- Quy trình 1 lối thoát.
- (Trong quy trình vỏ ban đầu) Đọc từ đường ống và tích lũy dữ liệu trong
ret
biến.
- Khi đường ống được đóng lại, tiếp tục thực hiện.
Như bạn có thể thấy, quy trình 1 tạo ra một quy trình khác, sau đó đợi cho nó kết thúc và thoát ngay lập tức. Sẽ hiệu quả hơn cho quy trình 1 để tự tái chế. Một số shell (và phiên bản shell) tốt hơn những cái khác trong việc nhận ra các tình huống như vậy và thực hiện tối ưu hóa cuộc gọi đuôi . Tuy nhiên, trong trường hợp ret=`{ ./segfault; } 2>&1`
, quy trình 2 có lỗi tiêu chuẩn được chuyển hướng đến mô tả tệp 1, nhưng quy trình 1 thì không. Trong phiên bản shell mà bạn đã thử, trình tối ưu hóa không nhận ra tình huống này (nó có thể đã thực hiện một cuộc gọi đuôi, nhưng nó nên thiết lập chuyển hướng khác nhau).