Một ví dụ tốt về các lệnh đường ống với nhau là gì?


33

Nếu bạn đang giúp ai đó tìm hiểu khái niệm về đường ống trên dòng lệnh, bạn sẽ sử dụng ví dụ nào? Ví dụ thực sự được đưa ra là như sau:

cat whatever.txt | less

Tôi cảm thấy đó không phải là ví dụ tốt nhất, cụ thể là vì chỉ có một bước. Thế nào là tốt, nhưng sử dụng cơ bản |?

Lý tưởng nhất là ví dụ tôi sẽ trình bày sẽ sử dụng các chương trình có đầu ra có thể chạy độc lập và sau đó hiển thị cùng nhau.


3
Ví dụ của bạn thực sự không tốt - về cơ bản nó là một đề cử cho giải thưởng vô dụng dành cho mèo.
maxschlepzig

@maxschlepzig Không phải bạn sai, nhưng bạn cũng không hữu ích lắm; bạn không cần catđiều đó vì nó less whatever.txthoạt động tốt.
Bora M. Alper

Câu trả lời:


34

Tôi sẽ dẫn bạn qua một ví dụ hơi phức tạp, dựa trên một kịch bản đời thực.

Vấn đề

Giả sử lệnh conkydừng phản hồi trên máy tính để bàn của tôi và tôi muốn giết nó bằng tay. Tôi biết một chút về Unix, vì vậy tôi biết rằng những gì tôi cần làm là thực thi lệnh kill <PID>. Để lấy PID, tôi có thể sử dụng pshoặc tophoặc bất cứ công cụ phân phối Unix của tôi đã cho tôi. Nhưng làm thế nào tôi có thể làm điều này trong một lệnh?

Câu trả lời

$ ps aux | grep conky | grep -v grep | awk '{print $2}' | xargs kill

TUYÊN BỐ TỪ CHỐI: Lệnh này chỉ hoạt động trong một số trường hợp nhất định. Không sao chép / dán nó vào thiết bị đầu cuối của bạn và bắt đầu sử dụng nó, nó có thể giết chết các quá trình không nghi ngờ. Thay vì học cách xây dựng nó .

Làm thế nào nó hoạt động

1- ps aux

Lệnh này sẽ xuất danh sách các tiến trình đang chạy và một số thông tin về chúng. Thông tin thú vị là nó sẽ xuất ra PID của từng quy trình trong cột thứ 2 của nó. Đây là một trích xuất từ ​​đầu ra của lệnh trên hộp của tôi:

$ ps aux
 rahmu     1925  0.0  0.1 129328  6112 ?        S    11:55   0:06 tint2
 rahmu     1931  0.0  0.3 154992 12108 ?        S    11:55   0:00 volumeicon
 rahmu     1933  0.1  0.2 134716  9460 ?        S    11:55   0:24 parcellite
 rahmu     1940  0.0  0.0  30416  3008 ?        S    11:55   0:10 xcompmgr -cC -t-5 -l-5 -r4.2 -o.55 -D6
 rahmu     1941  0.0  0.2 160336  8928 ?        Ss   11:55   0:00 xfce4-power-manager
 rahmu     1943  0.0  0.0  32792  1964 ?        S    11:55   0:00 /usr/lib/xfconf/xfconfd
 rahmu     1945  0.0  0.0  17584  1292 ?        S    11:55   0:00 /usr/lib/gamin/gam_server
 rahmu     1946  0.0  0.5 203016 19552 ?        S    11:55   0:00 python /usr/bin/system-config-printer-applet
 rahmu     1947  0.0  0.3 171840 12872 ?        S    11:55   0:00 nm-applet --sm-disable
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:38 conky -q

2- grep conky

Tôi chỉ quan tâm đến một quy trình, vì vậy tôi sử dụng grepđể tìm mục tương ứng với chương trình của mình conky.

$ ps aux | grep conky
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:39 conky -q
 rahmu     3233  0.0  0.0   7592   840 pts/1    S+   16:55   0:00 grep conky

3- grep -v grep

Như bạn có thể thấy trong bước 2, lệnh psxuất ra grep conkyquy trình trong danh sách của nó (rốt cuộc đó là một quy trình đang chạy). Để lọc nó, tôi có thể chạy grep -v grep. Tùy chọn -vcho biết grepđể khớp với tất cả các dòng không bao gồm các dòng có chứa mẫu.

$ ps aux | grep conky | grep -v grep
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:39 conky -q

Lưu ý: Tôi rất muốn biết cách thực hiện bước 2 và 3 trong một grepcuộc gọi.

4- awk '{print $2}'

Bây giờ tôi đã cô lập quá trình mục tiêu của tôi. Tôi muốn lấy lại PID của nó. Nói cách khác, tôi muốn lấy từ thứ 2 của đầu ra. May mắn cho tôi, hầu hết (tất cả?) Các hợp nhất hiện đại sẽ cung cấp một số phiên bản awk, một ngôn ngữ kịch bản làm nên điều kỳ diệu với dữ liệu dạng bảng. Nhiệm vụ của chúng tôi trở nên dễ dàng như print $2.

$ ps aux | grep conky | grep -v grep | awk '{print $2}'
 1948

5- xargs kill

Tôi có PID. Tất cả tôi cần là để vượt qua nó kill. Để làm điều này, tôi sẽ sử dụng xargs.

xargs killsẽ đọc từ đầu vào (trong trường hợp của chúng ta từ đường ống), tạo thành một lệnh bao gồm kill <items>( <items>là bất cứ thứ gì nó đọc từ đầu vào), và sau đó thực hiện lệnh được tạo. Trong trường hợp của chúng tôi, nó sẽ thực thi kill 1948. Nhiệm vụ đã hoàn thành.

Từ cuối cùng

Lưu ý rằng tùy thuộc vào phiên bản unix nào bạn đang sử dụng, một số chương trình nhất định có thể hoạt động khác đi một chút (ví dụ: pscó thể xuất ra PID trong cột $ 3). Nếu có gì đó không đúng hoặc khác, hãy đọc tài liệu của nhà cung cấp của bạn (hoặc tốt hơn, các mantrang). Cũng nên cẩn thận vì đường ống dài có thể nguy hiểm. Đừng đưa ra bất kỳ giả định nào, đặc biệt là khi sử dụng các lệnh như killhoặc rm. Ví dụ: nếu có một người dùng khác tên là 'conky' (hoặc 'Aconkyous'), lệnh của tôi cũng có thể giết tất cả các quy trình đang chạy của anh ta!

Những gì tôi đang nói là cẩn thận, đặc biệt là đối với đường ống dài. Luôn luôn tốt hơn để xây dựng nó một cách tương tác như chúng ta đã làm ở đây, hơn là đưa ra các giả định và cảm thấy tiếc sau này.


Lưu ý: Tôi rất muốn biết một cách để thực hiện bước 2 và 3 trong một cuộc gọi grep duy nhất. -> grep "conky -q" :)
Wolfy

3
Trên thực tế đó là một ví dụ tồi tệ, như bạn có thể làm đơn giảnkill $(pgrep conky)
Patrick

5
Tôi biết điều này là muộn, nhưng bạn có thể đơn giản hóa nó hơn nữapkill conky
strugee

2
"" "NB: Tôi rất muốn biết cách thực hiện bước 2 và 3 trong một cuộc gọi grep duy nhất." đồng hành. Bằng cách đó, quá trình grep sẽ chỉ hiển thị là "grep" thay vì "grep conky" để nó không khớp với chính nó.
Random832

2
Lưu ý: Tôi rất muốn biết cách thực hiện bước 2 và 3 trong một grepcuộc gọi. grep [c]onkylà những gì bạn đang tìm kiếm.
AlexT

15

Yêu thích của tôi là cái này:

youtube-dl $1 -q -o - | ffmpeg -i - $2

tải xuống video từ url youtube đã cho đi qua $1và xuất ra dưới dạng tệp được cung cấp bởi $2. Lưu ý cách tập tin lặng lẽ -qxuất ra STDOUT -o -, được dẫn đến ffmpeg và được sử dụng làm đầu vào ở đó bởi -i -.

Đặc biệt đối với người mới sử dụng linux, đây có thể là một ví dụ điển hình tại sao dòng lệnh có thể hữu ích và giúp mọi việc dễ dàng hơn so với sử dụng các công cụ GUI. Tôi không chắc sẽ mất bao lâu để tải xuống video từ youtube và chuyển đổi âm thanh của nó sang mp3. Dòng trên có thể làm điều đó trong một vài giây.


3
youtube-dl có một tùy chọn chỉ lưu âm thanh. Lệnh thông thường của tôi là thế này, nơi URL xuất hiện trên stdin : youtube-dl --extract-audio --audio-format mp3 -a -. Vẫn là một ví dụ tuyệt vời, nhưng có nhiều cách dễ dàng hơn để làm điều đó. (Nó gọi ffmpeg trong nội bộ.)
Brigand

3
@FakeRainBrigand: Haha, thật tốt khi biết! Nhưng tôi có một giải pháp thay thế không nên tích hợp: phát youtube-dl $1 -q -o - | mplayer -trực tiếp video bên trong mplayer. Tôi sử dụng lệnh đó từ máy tính xách tay của mình để báo cho máy chủ của tôi (được kết nối với TV) để phát video. Tôi phải nối thêm -display :0.0 -geometry 400x300+1200+200để cho cửa sổ mplayer xuất hiện trên màn hình chính xác.
Baarn

9

Việc sử dụng chung (đọc: cách tôi sử dụng hầu hết thời gian) là khi, vì một số lý do, tôi phải chạy một số dữ liệu thông qua một số công cụ để thực hiện các tác vụ xử lý khác nhau.

Vì vậy, tôi muốn nói rằng việc sử dụng các đường ống là keo để lắp ráp một số khối xây dựng (các công cụ UNIX khác nhau) lại với nhau. Giống như Ulrich đã nói, sortuniqlà một khổ thơ phổ biến.

Tùy thuộc vào đối tượng, nếu bạn muốn làm nổi bật cách sử dụng ống này, ví dụ, bạn có thể bắt đầu bằng: "này, giáo trình này có liên kết đến một số tệp PDF thú vị với các bài báo và ghi chú bài giảng, nhưng một số trong số chúng được lặp lại. bằng cách nào đó tự động hóa điều này? "

Sau đó, bạn có thể hiển thị cách lynx --dump --listonlylấy danh sách các liên kết, cách greplọc các liên kết kết thúc .pdf, làm thế nào colrmhoặc sedcó thể loại bỏ các số lynxghi còn lại cho mỗi URL, làm thế nào sortuniqcó thể thoát khỏi các bản sao và cuối cùng wget -i -có thể được sử dụng để truy xuất tập tin (sử dụng --waitđể được nhẹ nhàng trên máy chủ, tất nhiên).

Tôi sợ đây là một ví dụ phức tạp. Mặt khác, nó có thể giúp thể hiện sức mạnh của đường ống khi bạn chỉ cần ống và vỏ chạy cùng một lúc.


2
Bạn cũng có thể sử dụng sort -utrong lõi GNU .
Teresa e Junior

2

Tôi không biết chính xác về điều tốt, nhưng đường ống grepphải là một trong những cách sử dụng phổ biến nhất, có thể được theo sau wc -l. (Có, grepcó công tắc ít được biết đến -c.)

Một khổ thơ phổ biến khác là | sort | uniq, nếu chỉ vì uniqyêu cầu đầu vào của nó được sắp xếp.


Hầu hết mọi người thích ... | sort -unếu có sẵn!

2

Không phải là bạn cần nó cho ví dụ này, nhưng:

$ ps aux | grep -v grep | grep conky

... đảo ngược thứ tự của các greps duy trì màu sắc, nhưng NHIỀU kém hiệu quả hơn. có lẽ trong danh sách lớn, màu sắc sẽ không thành vấn đề.

Ngoài ra, trang web này cho thấy:

https://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep

> Johnsyweb đã trả lời 21 tháng 2 '12 lúc 10:31
> Thủ thuật thông thường là:
> ps phụ | grep '[t] erminal'
> Điều này sẽ khớp với các dòng chứa thiết bị đầu cuối, mà grep '[t] erminal' không!
> Nó cũng hoạt động trên nhiều hương vị của Unix.

... nhưng điều đó sẽ không hoạt động nếu bạn đang tìm kiếm một chữ cái duy nhất (như tiến trình 'X').


2

Cuối cùng tôi cũng có thể chia sẻ mớ hỗn độn này của một oneliner tôi đã làm cách đây khoảng một năm rưỡi ...

while read in; do host "$in"; done < sites.txt | grep -iv "GOOGLE" | grep -E '1\.2\.3\.4|5\.6\.7\.8' | sed -e 's/has\ address\ 216.70.91.72//' | sed -e 's/has\ address\ 94.23.33.92//' | while read sites; do curl -sL -w "%{http_code} %{url_effective}\\n" "$sites" -o /dev/null; done | grep -ivE '4.*|5.*' | sed -e 's/200//' | sed -e 's/HTTP/http/'

Nó ...

  1. Đọc trang web.txt
  2. Chạy "máy chủ" trên mỗi (trong nhận thức muộn, đào + ngắn sẽ giúp việc này trở nên dễ dàng hơn)
  3. Xóa các dòng có chứa "GOOGLE" - đây là các bản ghi mx
  4. Nhận các dòng có một trong hai IP
  5. Nhận mã trạng thái http từ mỗi trang web trong danh sách
  6. Xóa các trang web trả về 4xx hoặc 5xx
  7. Loại bỏ "200" từ các trang web đã trả lại rằng
  8. Thay thế "HTTP" bằng "http" - hoàn toàn là thẩm mỹ, không có lý do thực sự.

Điều này có thể đã được thực hiện tốt hơn rất nhiều với một tập lệnh Python, tôi cá là vậy.


Uh ... Tôi không chắc đây sẽ là ví dụ sạch nhất và dễ nhất để giải thích đường ống cho người mới;)
Erathiel

2
Câu hỏi của tôi là, mục đích của nó là gì?
ADTC

Tôi đã có một tệp chứa đầy đủ các tên miền và tôi cần phải xem liệu chúng có ở một trong hai máy chủ của tôi không (mà tôi "đã kế thừa", thật không may). Điều này đọc tệp, "lưu trữ" và xóa đầu ra đó, sau đó chỉ thực hiện một yêu cầu để xem nếu nó trả về một lỗi 4xx hoặc 5xx. Nếu nó đã làm, thì nó sẽ loại bỏ tên miền; nếu không, nó xuất ra chúng và tôi đặt nó vào một tập tin khác.
thợ thuộc da

1

Đây là điều đầu tiên tôi nghĩ đến ...

mysqldumplà một ứng dụng giao diện điều khiển gửi dữ liệu, lược đồ và các thủ tục và hàm tùy chọn đến thiết bị xuất chuẩn. Thông thường, nó được chuyển hướng đến một tập tin để sao lưu.

mysqldump <options> > mydb.dump

Điều đó sẽ cung cấp cho bạn một kịch bản sql không nén. Để tiết kiệm dung lượng, bạn có thể nén nó bằng bzip2.

bzip2 mydb.dump

Ngoài ra, bạn có thể làm cả hai trong một bước:

mysqldump <options> | bzip2 > mydb.dump.bz2

Trong ví dụ này ở trên, thiết bị xuất chuẩn từ mysqldumpđược chuyển sang bzip2, sau đó đầu ra của nó được chuyển hướng đến một tệp.


1
Thêm các hoạt động đảo ngược quá : bzcat mydb.dump.bz2 | mysql <options>.
manatwork

1

Đây là một ví dụ tôi sử dụng trong công việc nhiều đường ống trong một lệnh. Điều này sử dụng gawk để tìm kiếm nhật ký truy vấn chung của MySQL ($ OFILE) và tìm bất kỳ thông tin đăng nhập bị từ chối nào. Sau đó, nó sắp xếp danh sách đó theo tên, các đường dẫn liệt kê đến uniq, trong đó đếm các lần xuất hiện, và sau đó sắp xếp nó lần cuối để sắp xếp danh sách được tính bằng số ...

gawk '{ for (x=1;x<=NF;x++) if ( $x~"Access" && $(x+4)~".*@.*") print $(x+4)}' $OFILE | sort | uniq -c | sort -n

1

Ống làm việc tốt nhất với các bộ lọc và dịch

find /usr/bin/ |                #produce 
sed 's:.*/::'  |                #translate: strip directory part
grep -i '^z'   |                #filter   : select items starting with z
xargs -d '\n' aFinalConsumer    #consume  

Bằng cách này, dữ liệu có thể truyền từ chương trình này sang chương trình tiếp theo và không có lúc nào tất cả dữ liệu phải ở trong bộ nhớ.


0

cat filename | less là một sử dụng khủng khiếp của đường ống vì bạn chỉ có thể làm less filename

Dưới đây là một ví dụ về pips mà tôi sử dụng hàng ngày (nhưng cũng có thể là một ví dụ tồi): ls -la | more -c

Câu trả lời của scott hoffman và njsg là những ví dụ tốt hơn.



0

thực hiện cái này trong bất kỳ thư mục nào bạn muốn có một phân tích được sắp xếp cho kích thước thư mục (sau đó cuộn xuống bằng phím END):

du -m| sort -n| less

Sắp xếp nach Ordnergrösse


0

Dưới đây là một ví dụ mà tôi đã sử dụng để đặt biến HIỂN THỊ khi xauth không phải là một tùy chọn ...

export DISPLAY=\`who am i |awk '{print $NF}' | sed 's/[()]//g'`":0.0"

Lệnh đầu tiên nhận được dữ liệu cần thiết, tức là tên máy chủ hoặc IP. Lệnh thứ hai chỉ lấy dữ liệu đó (trường cuối cùng). Cuối cùng, lệnh cuối cùng loại bỏ dấu ngoặc đơn từ dữ liệu.


0

Lệnh đường ống bạn có thể sử dụng bất cứ nơi nào bạn cảm thấy rằng đầu ra của lệnh đầu tiên có thể được cung cấp làm đầu vào tiếp theo.

Ví dụ.

  1. Với tệp văn bản, bạn có thể chuyển tệp văn bản tới grep để tìm các dòng văn bản cụ thể. Sau đó, bạn có thể chuyển đầu ra cho sed hoặc awk để sửa đổi hoặc in một phần của dòng.

ví dụ mèo txt | grep {some_line} | awk {some_command}

  1. Làm việc với quá trình bạn có thể sử dụng đường ống để gửi lệnh để giết tiến trình.

Nó chỉ đơn giản là khái niệm mà nếu bạn cảm thấy đầu ra của lệnh bạn đã chạy có thể là đầu vào của một lệnh khác, bạn có thể đặt chúng.

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.