Tôi đã nhận được lỗi "đường ống bị hỏng" từ Xcode một lần quá nhiều. Bây giờ tôi tò mò muốn biết chính xác đường ống là gì.
Khái niệm về một "đường ống" là gì và làm thế nào nó có thể bị "phá vỡ"?
Tôi đã nhận được lỗi "đường ống bị hỏng" từ Xcode một lần quá nhiều. Bây giờ tôi tò mò muốn biết chính xác đường ống là gì.
Khái niệm về một "đường ống" là gì và làm thế nào nó có thể bị "phá vỡ"?
Câu trả lời:
Một đường ống chỉ đơn giản là một cơ chế giao tiếp giữa các quá trình (IPC) được sử dụng để kết nối đầu ra tiêu chuẩn của một quá trình với đầu vào tiêu chuẩn của một quá trình khác.
Một ví dụ là khi bạn muốn tìm kiếm một tập tin cho từ "pax":
cat filename | grep pax
và vâng, tôi biết bạn có thể grep
trực tiếp gửi tệp nhưng điều đó không giải thích cách thức hoạt động của nó, phải không?
Điều này kết nối đầu ra tiêu chuẩn của cat
lệnh với đầu vào tiêu chuẩn của grep
lệnh. cat
gửi nội dung của tệp đến đầu ra tiêu chuẩn của nó và grep
đọc tệp của nó (trong trường hợp này) từ đầu vào tiêu chuẩn của nó. Bằng cách kết nối các quy trình với nhau như thế này, bạn có thể tạo các công cụ của riêng mình bao gồm bất kỳ số lượng phân đoạn ống nào. Những thứ như:
show_users | grep pax | awk -F: '{print $4}' | tr '[a-z]' '[A-Z]' | cut -c1-20
Một đường ống bị hỏng là một trong đó (thường) người nhận dữ liệu đã đóng kết nối trong khi người gửi vẫn đang cố gắng gửi nội dung qua.
Ví dụ: nếu bạn gửi một tệp lớn thông qua chương trình máy nhắn tin (để xem từng trang một):
cat myfile | pager
và sau đó thực hiện một CTRL-BREAK, điều này có thể khiến pager
quá trình tắt đường ống đầu vào của nó trước khi cat
sử dụng xong. Đó là một khả năng để có được đường ống bị hỏng này.
Từ một tìm kiếm đáng chú ý của Google , vấn đề cụ thể này dường như có liên quan đến việc triển khai đột xuất và các giải pháp được đưa ra thường bao gồm thoát hầu hết phần mềm của bạn và khởi động lại hầu hết các thiết bị của bạn.
Điều này có lẽ đủ nghiêm trọng để báo cáo vấn đề với Apple. Càng nhiều nhà phát triển phàn nàn về nó, nhiều khả năng sẽ có một cái gì đó được thực hiện để khắc phục nó.
pr -e4 -n ten-thousand-lines.c | sed 10q
kết thúc với một đường ống bị hỏng. Việc có pr
phiền để nói với bạn rằng nó có tín hiệu SIGPIPE hay không là một vấn đề khác; nó cũng có thể đơn giản là thoát do kết quả của tín hiệu (tạo ra trạng thái thoát khác không).
Các |
nhân vật thường được gọi là một đường ống. Trong các shell UNIX khác nhau (mà tôi biết), nó có thể được sử dụng để chuyển đầu ra của một lệnh sang đầu vào của một lệnh khác.
cat myfile.txt | head
Các head
lệnh chỉ cho thấy vài dòng đầu tiên của đầu vào của nó. Tại thời điểm đó, nó đóng đầu vào của nó. Điều này đặt ra một vấn đề cho lệnh đã tạo đầu vào. Nó viết đến đâu? Bất cứ khi nào chúng ta gặp phải tình huống này hoặc tình huống khi quá trình viết kết thúc trước khi người đọc thông qua, nó được gọi là "đường ống bị hỏng".
Để ngăn không cho cat
lệnh kéo dài mãi mãi, tiêu chuẩn UNIX xác định một tín hiệu đặc biệt ( SIGPIPE , tín hiệu 13 ) mà nó gửi đến cat
. Hành động mặc định cho tín hiệu này là để giết quá trình, điều này làm chocat
kết thúc độc đáo.
Có vẻ như ứng dụng bạn đang sử dụng đã cài đặt trình xử lý tín hiệu cho tất cả các tín hiệu, bao gồm SIGPIPE, tạo ra thông báo bật lên nhỏ mà bạn nhìn thấy.
Lỗi này dường như đến khá thường xuyên. /programming/490366/ad-hoc-deployment-su-putpkt-write-fails-broken-pipe it "... một lỗi nội bộ trong khả năng nói chuyện với điện thoại của Xcode. có nghĩa là bạn đã làm gì sai, đó là một lỗi trong hệ thống phát triển "
Một ống là một cơ chế IPC trên các hệ thống Unix. Một ống có hai đầu, một đầu đọc và một đầu ghi. Dữ liệu được ghi vào đầu ghi có thể được đọc từ đầu đọc và xuất hiện theo thứ tự được viết.
Trong thế giới dòng lệnh Unix, các đường ống là một cách rất phổ biến để nối các chương trình lại với nhau để hoàn thành công việc. Ví dụ sed 's/foo/bar/g' fred.txt | grep -e 'bar.*baz'
sẽ đọc trong tệp fred.txt
thay thế tất cả các phiên bản của chuỗi foo
bằng chuỗi bar
sau đó tìm kiếm kết quả cho các dòng có chứa bar
một số ký tự, sau đóbaz
.
Điều đó, tất nhiên, dường như không hữu ích lắm. Nhưng tôi chắc chắn nếu bạn nghĩ về nó rằng bạn có thể thấy làm thế nào bạn có thể đưa nó vào tất cả các loại sử dụng thú vị, đặc biệt là khi bạn có các chương trình như awk
hoặcperl
theo ý của bạn.
Hệ thống đường ống đã là một phần của Unix từ rất sớm. Và nếu một quá trình trong đường ống của bạn thoát ra, bạn thường muốn tất cả các chương trình trong đường ống thoát ra. Điều này có nghĩa là theo mặc định, một quá trình ghi vào một đường ống là quá trình ở đầu đọc bị mất sẽ nhận được SIGPIPE
tín hiệu. Và nếu tín hiệu đó bị chặn, tín hiệu write
đó vẫn thất bại với một loại lỗi đặc biệt cho biết đường ống đã bị 'vỡ'.
Việc xử lý mặc định SIGPIPE
giết chết quá trình nhận được nó. Và nếu nó không phải là 'đầu' của đường ống, thì toàn bộSIGPIPE
lan truyền sẽ sao lưu chuỗi.
Điều mà Xcode đang phàn nàn là nó đã bắt đầu một số chương trình phụ để làm một cái gì đó với một đường ống dẫn đến nó, và chương trình phụ đó đã chết bất ngờ khiến đường ống bị vỡ ..
Một đường ống bị hỏng của người Viking là một trong đó một đầu đã bị close()
'và đầu kia đang được đọc hoặc ghi vào. Ví dụ, trong lệnh shell sau:
cat foo | less
Các cat
quá trình giữ viết cuối đường ống, và các less
quá trình đọc một. Nếu quá trình đọc đóng đường ống, đường ống bị hỏng (và do đó vô dụng); quá trình người viết sẽ nhận được lỗi đường ống bị hỏng của người dùng từ hệ điều hành.
cat
rõ ràng là ngay sau khi nó kết thúc), người đọc sẽ chỉ thấy một tập tin cuối bình thường.