Apa contoh yang baik dari perintah perpipaan bersama?

33

Jika Anda membantu seseorang mempelajari konsep pipa pada baris perintah, contoh apa yang akan Anda gunakan? Contoh yang benar-benar muncul adalah sebagai berikut:

cat whatever.txt | less

Saya merasa itu bukan contoh terbaik, yaitu karena hanya ada satu langkah. Apa yang baik, tetapi fundamental, penggunaan |?

Idealnya contoh yang akan saya presentasikan akan menggunakan program yang memiliki output sendiri yang dapat dijalankan secara independen dan kemudian ditampilkan disalurkan bersama.

Matius
sumber
3
Contoh Anda benar-benar tidak begitu baik - itu pada dasarnya adalah nominasi untuk penghargaan kucing yang tidak berguna.
maxschlepzig
@maxschlepzig Bukan berarti Anda salah, tetapi Anda juga tidak terlalu membantu; Anda tidak perlu catuntuk itu karena less whatever.txtberfungsi dengan baik.
Bora M. Alper

Jawaban:

34

Saya akan memandu Anda melalui contoh yang agak rumit, berdasarkan skenario kehidupan nyata.

Masalah

Katakanlah perintah conkyberhenti merespons pada desktop saya, dan saya ingin membunuhnya secara manual. Saya tahu sedikit tentang Unix, jadi saya tahu apa yang perlu saya lakukan adalah menjalankan perintah kill <PID>. Untuk mengambil PID, saya bisa menggunakan psatau topalat apa pun yang diberikan distribusi Unix saya. Tetapi bagaimana saya bisa melakukan ini dalam satu perintah?

Menjawab

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

PENOLAKAN: Perintah ini hanya berfungsi dalam kasus-kasus tertentu. Jangan menyalin / menempelnya di terminal Anda dan mulai menggunakannya, itu bisa membunuh proses tanpa curiga. Alih-alih belajar bagaimana membangunnya .

Bagaimana itu bekerja

1- ps aux

Perintah ini akan menampilkan daftar proses yang sedang berjalan dan beberapa info tentangnya. Info yang menarik adalah bahwa ia akan menampilkan PID dari setiap proses di kolom ke-2. Berikut ini kutipan dari output perintah pada kotak saya:

$ 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

Saya hanya tertarik pada satu proses, jadi saya gunakan grepuntuk menemukan entri yang sesuai dengan program saya 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

Seperti yang Anda lihat di langkah 2, perintah psmenampilkan grep conkyproses dalam daftar (setelah semua itu proses yang berjalan). Untuk memfilternya, saya bisa menjalankan grep -v grep. Opsi -vmemberi tahu grepuntuk mencocokkan semua baris kecuali yang mengandung pola.

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

NB: Saya ingin tahu cara melakukan langkah 2 dan 3 dalam satu greppanggilan.

4- awk '{print $2}'

Sekarang saya telah mengisolasi proses target saya. Saya ingin mengambil PID-nya. Dengan kata lain saya ingin mengambil kata ke-2 dari output. Beruntung bagi saya, sebagian besar (semua?) Unix modern akan menyediakan beberapa versi awk, bahasa scripting yang sangat menakjubkan dengan data tabular. Tugas kita menjadi semudah print $2.

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

5- xargs kill

Saya punya PID. Yang saya butuhkan hanyalah meneruskannya kill. Untuk melakukan ini, saya akan gunakan xargs.

xargs killakan membaca dari input (dalam kasus kami dari pipa), membentuk perintah yang terdiri dari kill <items>( <items>apa pun itu dibaca dari input), dan kemudian jalankan perintah yang dibuat. Dalam kasus kami ini akan dieksekusi kill 1948. Misi selesai.

Kata-kata terakhir

Perhatikan bahwa tergantung pada versi unix yang Anda gunakan, program tertentu mungkin berperilaku sedikit berbeda (misalnya, psmungkin menampilkan PID di kolom $ 3). Jika ada yang salah atau berbeda, baca dokumentasi vendor Anda (atau lebih baik, manhalaman). Juga hati-hati karena pipa panjang bisa berbahaya. Jangan membuat asumsi apa pun terutama ketika menggunakan perintah seperti killataurm . Sebagai contoh, jika ada pengguna lain bernama 'conky' (atau 'Aconkyous') perintah saya dapat membunuh semua proses yang berjalan juga!

Yang saya katakan adalah hati-hati, terutama untuk pipa panjang. Itu selalu lebih baik untuk membangunnya secara interaktif seperti yang kami lakukan di sini, daripada membuat asumsi dan merasa menyesal nanti.

rahmu
sumber
NB: Saya ingin tahu cara melakukan langkah 2 dan 3 dalam satu panggilan grep. -> grep "conky -q" :)
Wolfy
3
Sebenarnya itu adalah contoh yang buruk, seperti yang bisa Anda lakukankill $(pgrep conky)
Patrick
5
Saya tahu ini terlambat, tetapi Anda dapat menyederhanakannya lebih jauh kepkill conky
strugee
2
"" "NB: Saya ingin tahu cara melakukan langkah 2 dan 3 dalam satu panggilan grep." "" Alih-alih "aux" gunakan "-o pid, comm" - ini juga lebih portabel karena POSIX patuh. Dengan begitu proses grep hanya akan muncul sebagai "grep" bukan "grep conky" sehingga tidak akan cocok dengan dirinya sendiri.
Random832
2
NB: Saya ingin tahu cara melakukan langkah 2 dan 3 dalam satu greppanggilan. grep [c]onkyadalah apa yang kamu cari.
AlexT
15

Favorit saya adalah yang ini:

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

mengunduh video dari url youtube yang diberikan yang dilewati $1dan mengeluarkannya sebagai file yang diberikan oleh $2. Perhatikan bagaimana file diam-diam -qoutput ke STDOUT -o -, disalurkan ke ffmpeg dan digunakan sebagai input oleh -i -.

Khusus untuk pemula linux, ini mungkin contoh praktis mengapa baris perintah dapat bermanfaat dan membuat segalanya lebih mudah daripada menggunakan alat GUI. Saya tidak yakin berapa lama untuk mengunduh video dari youtube dan mengonversi suaranya menjadi mp3. Baris di atas dapat melakukannya dalam beberapa detik.

Baarn
sumber
3
youtube-dl memiliki opsi untuk hanya menyimpan audio. Perintah biasa saya adalah ini, di mana URL datang pada stdin: youtube-dl --extract-audio --audio-format mp3 -a -. Masih merupakan contoh yang keren, tetapi ada cara yang lebih mudah untuk melakukannya. (Ini memanggil ffmpeg secara internal.)
Brigand
3
@FakeRainBrigand: Haha, senang tahu! Tapi saya punya alternatif yang tidak boleh ada di youtube-dl $1 -q -o - | mplayer -dalamnya : langsung memutar video di dalam mplayer. Saya menggunakan perintah itu dari laptop saya untuk memberi tahu server saya (yang terhubung ke TV) untuk memutar video. Saya harus menambahkan -display :0.0 -geometry 400x300+1200+200untuk membiarkan jendela mplayer muncul di layar yang benar.
Baarn
9

Penggunaan umum (baca: cara saya menggunakannya sebagian besar waktu) adalah ketika, untuk beberapa alasan, saya harus menjalankan beberapa data melalui beberapa alat untuk melakukan tugas pemrosesan yang berbeda.

Jadi saya akan mengatakan itu penggunaan pipa adalah sebagai lem untuk merakit beberapa blok bangunan (alat UNIX yang berbeda) bersama-sama. Seperti kata Ulrich, sortdan uniqmerupakan bait yang umum.

Bergantung pada audiens, jika Anda ingin menyoroti penggunaan pipa ini, Anda dapat, misalnya, mulai dengan: "hei, silabus ini memiliki tautan ke beberapa PDF menarik dengan makalah dan catatan kuliah, tetapi beberapa di antaranya diulang. Dapatkah saya entah bagaimana mengotomatiskan ini? "

Lalu Anda bisa menunjukkan bagaimana lynx --dump --listonlymendapatkan daftar tautan, bagaimana grepbisa memfilter untuk tautan yang berakhir .pdf, bagaimana colrmatau sedbisa menghilangkan angka-angka yang lynxdituliskan ke setiap URL, bagaimana sortdan uniqbisa menghilangkan duplikat, dan akhirnya bagaimana wget -i -bisa digunakan untuk mengambil kembali file (menggunakan--wait untuk bersikap lembut di server, tentu saja).

Saya khawatir ini adalah contoh yang kompleks. Di sisi lain, ini mungkin membantu menunjukkan kekuatan pipa ketika Anda hanya pipa dan membuat shell menjalankannya sekaligus.

njsg
sumber
2
Anda dapat menggunakan sort -udalam GNU coreutils juga.
Teresa e Junior
2

Saya tidak benar-benar tahu tentang yang baik, tetapi menyalurkan melalui grepharus menjadi salah satu kegunaan yang paling umum, mungkin diikuti oleh wc -l. (Ya, grepmemiliki -csaklar yang kurang dikenal .)

Bait umum lainnya adalah | sort | uniq, jika hanya karena uniqmembutuhkan inputnya untuk diurutkan.

Ulrich Schwarz
sumber
Kebanyakan orang lebih suka ... | sort -ujika tersedia!
2

Bukan berarti Anda membutuhkannya untuk contoh ini, tetapi:

$ ps aux | grep -v grep | grep conky

... membalik urutan greps mempertahankan pewarnaan, tetapi JAUH kurang efisien. mungkin pada daftar besar, warna tidak masalah.

juga, halaman web ini menyarankan:

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

> Johnsyweb menjawab 21 Feb '12 pukul 10:31
> Trik yang biasa adalah ini:
> ps aux | grep '[t] erminal'
> Ini akan cocok dengan baris yang berisi terminal, yang grep '[t] erminal' tidak!
> Ini juga berfungsi pada banyak rasa Unix.

... tetapi itu tidak akan berfungsi jika Anda mencari satu huruf (seperti proses 'X').

penggunaan anonim
sumber
2

Saya akhirnya bisa berbagi kekacauan tentang oneliner yang saya buat sekitar satu setengah tahun yang lalu ...

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/'

Saya t...

  1. Baca sites.txt
  2. Menjalankan "host" pada masing-masing (di belakang, gali + pendek akan membuat ini lebih mudah)
  3. Menghapus baris yang berisi "GOOGLE" - ini adalah catatan mx
  4. Mendapat garis yang memiliki satu dari dua IP
  5. Mendapat kode status http dari setiap situs dalam daftar
  6. Menghapus situs yang mengembalikan 4xx atau 5xx
  7. Hapus "200" dari situs yang mengembalikannya
  8. Mengganti "HTTP" dengan "http" - murni estetika, tanpa alasan nyata.

Ini bisa dilakukan jauh lebih baik dengan satu skrip Python, saya yakin.

penyamak
sumber
Uh ... Saya tidak yakin ini akan menjadi contoh terbersih dan termudah untuk menjelaskan perpipaan kepada seorang pemula;)
Erathiel
2
Pertanyaan saya adalah, apa tujuannya?
ADTC
Saya memiliki file yang penuh dengan domain, dan saya perlu melihat apakah mereka ada di salah satu dari dua server saya (sayangnya saya "mewarisi"). Ini membaca file, apakah "host" dan membersihkan output itu, kemudian hanya melakukan permintaan untuk melihat apakah ia mengembalikan kesalahan 4xx atau 5xx. Jika ya, maka itu akan membuang domain; jika tidak, itu output mereka dan saya taruh di file lain.
penyamak
1

Ini adalah hal pertama yang terlintas dalam pikiran saya ...

mysqldumpadalah aplikasi konsol yang mengirimkan data, skema, serta prosedur dan fungsi opsional ke stdout. Biasanya itu akan diarahkan ke file untuk cadangan.

mysqldump <options> > mydb.dump

Itu akan memberi Anda skrip sql yang tidak terkompresi. Untuk menghemat ruang, Anda bisa mengompresnya dengan bzip2.

bzip2 mydb.dump

Atau, Anda bisa melakukan keduanya dalam satu langkah:

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

Dalam contoh ini di atas, stdout dari mysqldumpdisalurkan ke bzip2 yang kemudian hasilnya dialihkan ke file.

Sean C.
sumber
1
Menambahkan operasi terbalik juga: bzcat mydb.dump.bz2 | mysql <options>.
manatwork
1

Berikut adalah contoh yang saya gunakan dalam pekerjaan saya dari banyak pipa dalam satu perintah. Ini menggunakan gawk untuk mencari log permintaan umum MySQL ($ OFILE) dan menemukan semua login yang ditolak. Ini kemudian mengurutkan daftar itu dengan nama, pipa yang daftar ke uniq yang menghitung kejadian, dan kemudian pipa itu mengurutkan untuk terakhir kalinya untuk mengurutkan daftar yang dihitung secara numerik ...

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

Pipa bekerja paling baik dengan filter dan penerjemah

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

Dengan cara ini, data dapat mengalir dari satu program ke program berikutnya dan tidak ada gunanya semua data harus ada di memori sekaligus.

PSkocik
sumber
0

cat filename | less adalah penggunaan pipa yang mengerikan karena Anda bisa melakukannya less filename

Berikut adalah contoh pip yang saya gunakan setiap hari (tetapi mungkin juga contoh buruk): ls -la | more -c

Scott hoffman dan njsg jawaban adalah contoh yang lebih baik.

DwB
sumber
0

jalankan ini di direktori mana saja yang Anda inginkan memiliki analisis diurutkan untuk ukuran folder (lalu gulir ke bawah dengan tombol END):

du -m| sort -n| less

Sortiert nach Ordnergrösse

xubunuser
sumber
0

Berikut adalah contoh yang saya gunakan untuk mengatur variabel DISPLAY ketika xauth bukan pilihan ...

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

Perintah pertama mendapatkan data yang dibutuhkan, yaitu, nama host atau IP. Perintah kedua hanya mendapatkan data itu (bidang terakhir). Akhirnya, perintah terakhir menghapus tanda kurung dari data.

Scott Hoffman
sumber
0

Command piping dapat Anda gunakan di mana saja Anda merasa bahwa output dari perintah pertama dapat dimasukkan sebagai input untuk selanjutnya.

Contohnya.

  1. Dengan file teks, Anda dapat meneruskan file teks ke grep untuk menemukan baris teks tertentu. Kemudian Anda dapat meneruskan output ke sed atau awk untuk mengubah atau mencetak bagian tertentu dari garis.

cat example txt | grep {some_line} | awk {some_command}

  1. Bekerja dengan proses, Anda dapat menggunakan perpipaan untuk mengirim perintah untuk mematikan proses.

Ini hanya konsep bahwa jika Anda merasa output dari perintah yang Anda jalankan dapat menjadi input dari perintah lain, Anda dapat menyalurkannya.

Piyush Jain
sumber