Ký hiệu ống linux linux | | làm gì? [bản sao]


23

Đây là một lệnh sắp xếp các tệp trong một thư mục theo thứ tự ngược lại

ls | sort -r

Không những gì |biểu tượng trong lệnh đó làm gì?

Điều tôi thực sự tìm kiếm ở đây là giải thích cấp cao (dễ hiểu) về các đường ống cho người mới bắt đầu Linux. Tôi thấy các câu hỏi khác về các đường ống ở đây trên Superuser, nhưng không có gì gợi ra câu trả lời giải thích một cách đơn giản những gì chúng làm và cách chúng khác với chuyển hướng ( biểu tượng >hoặc <).


7
Điều này không liên quan gì đến Linux (vốn là kernel). Ống nói chung là một phương tiện để định hướng lại đầu vào / đầu ra, trong một vỏ như bash nó không khác nhau. Điều duy nhất đặc biệt ở a |là nó không sử dụng tên, đầu ra từ lệnh l-hand được truyền trực tiếp đến đầu vào cho lệnh ở phía r-hand của ống.
Andon M. Coleman

Để có một bài học lịch sử về chủ đề này, hãy đọc linfo.org/pipe.html
Fredrik Pihl

ls -1r(Lưu ý đối số số một) sẽ tạo ra kết quả tương tự ls | sort -r.
Ivan Châu

Tôi muốn giải thích nó theo cách đó: Một đường ống lấy đầu ra của một lệnh và làm cho nó có thể sử dụng được cho một lệnh sau. Ví dụ, bạn có thể làm cat /somefile | grep cool. Điều này sẽ lấy đầu ra của somefile và làm cho nó có sẵn cho grep, và sau đó grep sẽ in tất cả các dòng có từ mát trong đó.
JohnDoea

Câu trả lời:


26

Sau đây được đơn giản hóa một chút để giúp người dùng mới.

Chà, trước tiên, cần phải hiểu khái niệm đầu vào tiêu chuẩn và đầu ra tiêu chuẩn.

Trong Linux và các hệ điều hành tương tự UNIX khác, mỗi quy trình có một đầu vào tiêu chuẩn ( stdin) và đầu ra tiêu chuẩn ( stdout). Tình huống thông thường là stdinbàn phím của bạn và stdoutlà cửa sổ màn hình hoặc thiết bị đầu cuối của bạn.

Vì vậy, khi bạn chạy ls, nó sẽ ném đầu ra của nó stdout. Nếu bạn không làm gì khác, nó sẽ đi đến màn hình hoặc cửa sổ đầu cuối của bạn và bạn sẽ xem nó.

Bây giờ, một số lệnh Linux tương tác với người dùng và sử dụng stdinđể làm điều đó, trình soạn thảo văn bản của bạn là một trong số đó. Nó đọc từ stdinđể chấp nhận tổ hợp phím của bạn, làm mọi thứ và sau đó viết nội dung stdout.

Tuy nhiên, cũng có những lệnh không tương tác hoặc "bộ lọc" KHÔNG hoạt động tương tác mà muốn có một loạt dữ liệu. Các lệnh này sẽ lấy mọi thứ stdincó, làm một cái gì đó cho nó, và sau đó ném nó vàostdout

Chúng ta hãy xem một lệnh khác được gọi là du- viết tắt của việc sử dụng đĩa. du /usr, ví dụ, sẽ in ra (để stdoutgiống như bất kỳ lệnh Linux nào khác) một danh sách mọi tệp trong thư mục đó và kích thước của nó:

# du /usr
2312    /usr/games
124     /usr/lib/tc
692     /usr/lib/rygel-1.0
400     /usr/lib/apt/methods
40      /usr/lib/apt/solvers
444     /usr/lib/apt
6772    /usr/lib/gnash

Như bạn có thể nói ngay ra con dơi, nó không được sắp xếp và bạn có thể muốn nó được sắp xếp theo thứ tự kích thước.

sortlà một trong những lệnh "bộ lọc" sẽ lấy một loạt các thứ từ đó stdinvà sắp xếp nó.

Vì vậy, nếu chúng ta làm điều này:

# du /usr | sort -nr

chúng tôi nhận được điều này, tốt hơn một chút:

4213348 /usr
2070308 /usr/lib
1747764 /usr/share
583668  /usr/lib/vmware
501700  /usr/share/locale
366476  /usr/lib/x86_64-linux-gnu
318660  /usr/lib/libreoffice
295388  /usr/lib/vmware/modules
290376  /usr/lib/vmware/modules/binary
279056  /usr/lib/libreoffice/program
216980  /usr/share/icons

Và bây giờ bạn có thể thấy rằng "đường ống" kết nối stdoutmột lệnh này với lệnh stdinkhác. Thông thường, bạn sẽ sử dụng nó trong các tình huống như thế này nơi bạn muốn lọc, sắp xếp hoặc thao tác đầu ra của lệnh. Chúng có thể được xếp tầng nếu bạn muốn xử lý đầu ra thông qua nhiều lệnh loại bộ lọc.

Nếu bạn gõ một sortmình, nó vẫn sẽ cố đọc từ đó stdin. Vì stdinđược kết nối với bàn phím của bạn, nó sẽ chờ bạn nhập và xử lý mọi thứ cho đến khi bạn nhấn Control-D. Nó sẽ không nhắc bạn vì nó không thực sự được sử dụng tương tác.

Một chương trình có thể cho biết liệu stdincó tương tác hay không, vì vậy một số chương trình có thể hoạt động khác đi nếu bạn tự phát hành chúng hoặc ở cuối đường ống.

Ngoài ra, đường ống một chương trình chỉ hoạt động tương tác, như vi, sẽ dẫn đến bạn có một thời gian tồi tệ.

Các đường ống khác với chuyển hướng ở chỗ dữ liệu được xáo trộn từ lệnh này sang lệnh khác mà không được lưu trữ ở bất cứ đâu. Vì vậy, trong ví dụ trên, duđầu ra của không được lưu trữ ở bất cứ đâu. Phần lớn thời gian bạn không muốn điều này với các đường ống vì lý do sử dụng đường ống là để xử lý đầu ra của một lệnh theo một cách nào đó - nhưng, có một lệnh teecho phép bạn có bánh của bạn và cũng ăn nó, nó sẽ sao chép những gì nó nhận được từ stdincả hai stdoutvà một tập tin bạn chọn. Bạn cũng có thể làm điều này bashvới một số cú pháp phức tạp liên quan đến ký hiệu và dấu ngoặc mà tôi không biết.


Lưu ý rằng điều này không phải là duy nhất đối với Linux, hoặc thậm chí POSIX. Hầu hết (tất cả?) Shell trên Windows cũng làm điều này. Và có lẽ các hệ điều hành khác.
Bob

Tôi biết khái niệm về stdinstdoutkhác với Windows so với Linux, mặc dù có lẽ không nhiều theo quan điểm của Windows cmd.exehoặc Powershell.
LawrenceC

Tôi khá tò mò về sự khác biệt của nó - bạn có phiền giải thích không? Có thể trong trò chuyện nếu bình luận không phải là một nơi tốt cho nó.
Bob

1
Các chương trình Win32 chắc chắn có đầu vào và đầu ra tiêu chuẩn. Ví dụ: bạn có thể truy xuất xử lý đầu vào, đầu ra hoặc xử lý lỗi tiêu chuẩn của quy trình với chức năng Win32 GetStdHandle(). Việc chuyển hướng các luồng tiêu chuẩn của quy trình [con] sinh ra với .NET cũng rất đơn giản, mà tôi tin rằng ánh xạ tới các hàm Win32 (nhưng tôi không chắc chắn 100% về điều đó - Tôi không phải là nhà phát triển Win32).
Bob

1
À, đây là tương đương Win32, bằng cách đặt các tham số thích hợp trong STARTUPINFOcấu trúc cho CreateProcess().
Bob

27

Nếu bạn cảm thấy thoải mái với chuyển hướng đầu ra và đầu vào, việc giải thích thực sự khá dễ dàng.

Command1 | Command2

làm giống như

Command1 > tempfile
Command2 < tempfile

nhưng không có tempfile. Đầu ra của Command1được kết nối trực tiếp với đầu vào Command2và quá trình truyền xảy ra trong bộ nhớ.


Tôi có thể sai nhưng tôi nghĩ tempfile tồn tại ngay cả trong cú pháp ống. Nó không có tên.
Taemyr

3
Không nó không. Không có hoạt động hệ thống tệp nào được tham gia khi đầu ra đường ống từ một lệnh này sang đầu vào của lệnh khác.
Daniel B

1
Mặc dù, trong DOS (và rất có thể là Windows), một tệp tạm thời được tạo bởi đường ống. Không phải * nix, nhưng không có gì khác biệt.
Jeremy J Starcher

Tôi khá chắc chắn rằng điều này là không chính xác. Giám sát quy trình báo cáo không có CreateFilehoặc WriteFilecác cuộc gọi để yêu cầu bồi thường của bạn. / chỉnh sửa: Tất nhiên đó là phần Windows.
Daniel B

3

Thực sự nếu bạn muốn biết những gì ống dẫn làm và sự khác biệt giữa> và |, thì hãy đi đến một thư mục có rất nhiều tệp và

từ thiết bị đầu cuối ls so với ls | more (hoặc thực hiện điều đó từ Windows với DIR và DIR | THÊM)

Nếu bạn đã sử dụng> nhiều hơn, bạn sẽ thấy nó tạo ra một tệp có tên 'more' thay vì gửi đầu ra của ls đến lệnh 'more'. Vì vậy, nếu ai đó đã làm> nhiều hơn thì đó có thể là một lỗi, người ta sẽ không làm> nhiều hơn bạn làm> file1. Thêm là một lệnh nổi tiếng.

<Giống như> cũng là để liên kết một lệnh và một tệp, chứ không phải là một lệnh với một lệnh. Nhưng trong khi> gửi đầu ra của lệnh tới một tệp, <gửi tệp dưới dạng đầu vào cho lệnh. Tôi hiếm khi sử dụng <vì tôi thường sử dụng tập tin mèo1 | để gửi đầu ra của một tập tin đến một lệnh.

$ grep a <file1 abc

$ tập tin mèo1 | grep a abc

grep với 2 tham số là của tệp mẫu grep mẫu. grep với một tham số là mẫu grep. Và bạn có thể gửi tệp bằng cách chuyển nội dung của tệp tới tệp hoặc bằng cách sử dụng <. Nếu sử dụng <, bạn viết tên lệnh trước, sau đó là tên tệp sau lệnh <file. Nếu sử dụng | để dẫn nội dung của tệp, bạn sử dụng tệp cat1 | chỉ huy.

Ngoài ra, nhiều lệnh lấy một tệp làm đầu vào vì vậy grep một tệp1 sẽ hoạt động, giống như tệp cat1 | grep a và grep a <file1.

Tôi đã làm ống dẫn (|) và> trên DOS thậm chí 15 năm trước.

Để tóm tắt như thế nào | khác với <và> - Đường ống nằm giữa 2 lệnh <và> nằm giữa một lệnh và một tệp. > Là đầu ra cho một tập tin. <Là đầu vào từ một tập tin.


3

Ký tự ống ( |) kết nối đầu ra của một chương trình với đầu vào của một chương trình khác.

Trong ví dụ này echoin từ hellowc -cđếm số ký tự của đầu vào:

echo hello | wc -c

Tôi nghĩ bạn nên nói ngay rằng tiếng vang sẽ phát ra "hello \ n". Bạn không bảo OP học, bạn đang nói điều này với mọi người đọc câu trả lời của bạn. Tại sao nhân lên sự lãng phí thời gian này?
Rodrigo

Cảm ơn các phản hồi, tôi rút ngắn câu trả lời của tôi.
bbaassssiiee

2

Để hiểu điều này, hãy tự mình thử:

sort -r

Bây giờ bạn đang treo bằng một con trỏ và nó không làm gì cả. Điều gì xảy ra nếu bạn nhập một số dữ liệu?

1
2
3
5
4

Vẫn không có gì, phải không? Bây giờ nhấn ctrl + D

5
4
3
2
1

Vì vậy, những gì sắp xếp là, nó lấy đầu vào (những gì bạn đã nhập), làm một cái gì đó với nó (sắp xếp) và đưa nó trở lại như đầu ra. Các lslệnh không mất đầu vào, nó chỉ tạo ra. Biểu tượng ống lấy đầu ra từ lsvà cung cấp nó làm đầu vào cho sortlệnh.

>không cung cấp đầu ra cho một chương trình, nhưng lưu trữ đầu ra dưới dạng tệp. <sử dụng một tập tin như là đầu vào.

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.