Một đường ống của người Viking là gì và làm thế nào nó có thể bị hỏng?


12

nhập mô tả hình ảnh ở đây

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ỡ"?


3
Một ống là một ống dài chứa nhiều dữ liệu. Nếu đầu nhận của đường ống dừng kéo dữ liệu ra thì nó bắt đầu sao lưu và đường ống bị vỡ. Máy tính thông báo kết thúc đó là nhồi dữ liệu vào đường ống rằng điều này đã xảy ra.
Omnifarious

Câu trả lời:


7

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ể greptrự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 catlệnh với đầu vào tiêu chuẩn của greplệnh. catgử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 pagerquá trình tắt đường ống đầu vào của nó trước khi catsử 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ó.


Vậy đường ống "vỡ" là gì?
Moshe

pr -e4 -n ten-thousand-lines.c | sed 10qkết thúc với một đường ống bị hỏng. Việc có prphiề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).
Jonathan Leffler

Ống không nhất thiết phải kết nối đầu vào và đầu ra "tiêu chuẩn". Có thể lập trình để chuyển bất kỳ I / O nào qua một đường ống, mặc dù từ dòng lệnh bạn đã đúng.
CarlF

2

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 headlệ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 catlệ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.



1

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.txtthay thế tất cả các phiên bản của chuỗi foobằng chuỗi barsau đó tìm kiếm kết quả cho các dòng có chứa barmộ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ư awkhoặ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 SIGPIPEtí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 SIGPIPEgiế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ỡ ..


0

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 catquá trình giữ viết cuối đường ống, và các lessquá 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.


1
Trên thực tế, nó chỉ "bị hỏng" nếu người đọc đóng nó. Nếu người viết đóng nó ( catrõ 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.
Random832

Rất tiếc, bạn hoàn toàn chính xác ... Tôi sẽ cập nhật câu trả lời của tôi.
Michael Trausch
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.