Saya bertanya-tanya bagaimana kapan kita harus menggunakan pipa dan kapan kita seharusnya tidak.
Katakan misalnya, untuk menghentikan proses tertentu yang menangani file pdf, berikut ini tidak akan berfungsi dengan menggunakan pipa:
ps aux | grep pdf | awk '{print $2}'|kill
Sebagai gantinya, kita hanya bisa melakukannya dengan cara berikut:
kill $(ps aux| grep pdf| awk '{print $2}')
atau
ps aux | grep pdf | awk '{print $2}'| xargs kill
Menurut man bash
(versi 4.1.2
):
The standard output of command is connected via a pipe to the standard input of command2.
Untuk skenario di atas:
- stdin dari
grep
adalah stdout darips
. Itu bekerja. - stdin dari
awk
adalah stdout darigrep
. Itu bekerja. - stdin dari
kill
adalah stdout dariawk
. Itu tidak berhasil.
Stdin dari perintah berikut ini selalu mendapatkan input dari stdout perintah sebelumnya.
- Mengapa itu tidak berhasil
kill
ataurm
? - Apa yang berbeda antara
kill
,rm
input dengangrep
,awk
masukan? - Apakah ada aturannya?
pgrep
,pkill
dankillall
perintah.pgrep
dan sisanya dapat mencapai ini dengan sempurna :)Jawaban:
Ada dua cara umum untuk memberikan input ke program:
kill
hanya menggunakan argumen baris perintah. Itu tidak membaca dari STDIN. Program menyukaigrep
danawk
membaca dari STDIN (jika tidak ada nama file yang diberikan sebagai argumen baris perintah) dan memproses data sesuai dengan argumen baris perintah mereka (pola, pernyataan, bendera, ...).Anda hanya dapat menyalurkan ke STDIN dari proses lain, bukan ke perintah argumen baris.
Aturan umum adalah, bahwa program menggunakan STDIN untuk memproses jumlah data yang berubah-ubah. Semua parameter input tambahan atau, jika biasanya hanya sedikit, dilewatkan oleh argumen baris perintah. Jika baris perintah bisa menjadi sangat panjang, misalnya untuk
awk
teks program yang panjang , seringkali ada kemungkinan untuk membaca ini dari file program tambahan (-f
opsiawk
).Untuk menggunakan STDOUT program sebagai argumen baris perintah, gunakan
$(...)
atau jika ada banyak dataxargs
.find
bisa juga ini langsung dengan-exec ... {} +
.Untuk kelengkapan: Untuk menulis argumen baris perintah ke STDOUT, gunakan
echo
.sumber
gzip
dalam SYNOPSIS, tidak dikatakan harus mengambil FILENAME sebagai input. Saya melihat ada cara yang lebih sistematis untuk menentukan itu.xargs
tepat memungkinkan Anda untuk "pipa ke perintah argumen baris"?xargs
. Ini memanggil perintah jika perlu lebih dari sekali (ukuran baris perintah terbatas) dan memiliki banyak opsi lain.Ini adalah pertanyaan yang menarik, dan berkaitan dengan bagian dari filosofi Unix / Linux.
Jadi, apa perbedaan antara program-program seperti
grep
,sed
,sort
di satu sisi dankill
,rm
,ls
di sisi lain? Saya melihat dua aspek.The Filter Aspek
Jenis program pertama juga disebut filter . Mereka mengambil input, baik dari file atau dari STDIN, memodifikasinya, dan menghasilkan beberapa output, sebagian besar ke STDOUT. Mereka dimaksudkan untuk digunakan dalam pipa dengan program lain sebagai sumber dan tujuan.
Program jenis kedua bertindak berdasarkan input, tetapi output yang mereka berikan seringkali tidak terkait dengan input.
kill
tidak memiliki output ketika bekerja secara teratur, juga tidakls
. Hanya memiliki nilai balik untuk menunjukkan kesuksesan. Mereka biasanya tidak mengambil input dari STDIN, tetapi kebanyakan memberikan output ke STDOUT.Untuk program seperti
ls
, aspek filter tidak berfungsi dengan baik. Ini tentu saja dapat memiliki input (tetapi tidak memerlukannya), dan output terkait erat dengan input itu, tetapi tidak berfungsi sebagai filter. Namun, untuk program semacam itu, aspek lainnya masih berfungsi:The semantik Aspek
Untuk filter, inputnya tidak memiliki makna semantik . Mereka hanya membaca data, memodifikasi data, mengeluarkan data. Tidak masalah apakah ini daftar nilai numerik, beberapa nama file, atau kode sumber HTML. Arti dari data ini hanya diberikan oleh kode yang Anda berikan ke filter: regex untuk
grep
, aturan untukawk
atau program Perl.Untuk program lain, suka
kill
atauls
, inputnya memiliki makna , denotasi .kill
mengharapkan nomor proses,ls
mengharapkan nama file atau jalur. Mereka tidak dapat menangani data sewenang-wenang dan mereka tidak dimaksudkan untuk itu. Banyak dari mereka bahkan tidak memerlukan input atau parameter apa pun, sepertips
. Mereka biasanya tidak membaca dari STDIN.Orang mungkin bisa menggabungkan dua aspek ini: Filter adalah program yang inputnya tidak memiliki makna semantik untuk program tersebut.
Saya yakin saya telah membaca tentang filosofi ini di suatu tempat, tetapi saya tidak ingat sumber apa pun saat ini, maaf. Jika seseorang memiliki beberapa sumber hadir, silakan edit.
sumber
Tidak ada "aturan" seperti itu. Beberapa program menerima input dari STDIN, dan beberapa lainnya tidak. Jika suatu program dapat mengambil input dari STDIN, itu dapat disalurkan ke, jika tidak, itu tidak bisa.
Anda biasanya dapat mengetahui apakah suatu program akan mengambil input atau tidak dengan memikirkan apa yang dilakukannya. Jika pekerjaan program ini adalah untuk entah bagaimana memanipulasi isi dari file (misalnya
grep
,sed
,awk
dll), biasanya membutuhkan waktu masukan dari STDIN. Jika tugasnya adalah untuk memanipulasi file itu sendiri (misalnyamv
,rm
,cp
) atau proses (misalnyakill
,lsof
) atau untuk informasi kembali tentang sesuatu (misalnyatop
,find
,ps
) maka tidak.Cara lain untuk memikirkannya adalah perbedaan antara argumen dan input. Sebagai contoh:
Pada perintah di atas,
mv
tidak memiliki input seperti itu. Apa yang telah diberikan adalah dua argumen. Itu tidak tahu atau peduli apa yang ada di salah satu file, hanya tahu itu adalah argumennya dan itu harus memanipulasi mereka.Di samping itu
Di sini,
sed
telah diberikan input sekaligus argumen. Karena membutuhkan input, ia dapat membacanya dari STDIN dan dapat disalurkan ke.Semakin rumit ketika sebuah argumen bisa menjadi input. Sebagai contoh
Di sini,
file
adalah argumen yang diberikan kepadacat
. Lebih tepatnya, nama filefile
adalah argumen. Namun, karenacat
merupakan program yang memanipulasi isi file, inputnya adalah apa pun yang ada di dalamnyafile
.Ini dapat diilustrasikan menggunakan
strace
, program yang melacak panggilan sistem yang dibuat oleh proses. Jika kita jalankancat foo
viastrace
, kita dapat melihat bahwa filefoo
dibuka:Baris pertama di atas menunjukkan bahwa program
/bin/cat
dipanggil dan argumennya adalahcat
danfoo
(argumen pertama selalu merupakan program itu sendiri). Kemudian, argumenfoo
dibuka dalam mode hanya baca. Sekarang, bandingkan dengan iniDi sini juga,
ls
mengambil sendiri danfoo
sebagai argumen. Namun, tidak adaopen
panggilan, argumen tersebut tidak diperlakukan sebagai input. Sebaliknya,ls
panggilstat
pustaka sistem (yang tidak sama denganstat
perintah) untuk mendapatkan informasi tentang file tersebutfoo
.Singkatnya, jika perintah yang Anda jalankan akan membaca inputnya, Anda bisa mem-pipe ke sana, jika tidak, Anda tidak bisa.
sumber
kill
danrm
tidak perlu STDIN.Untuk
kill
danrm
, pengguna memberikan informasi khusus mereka sebagai argumen, dan$(cmd)
membantu mengambil STDOUT daricmd
dan mengonversinya argumen info.Untuk
grep
danawk
, pengguna memberikan argumen dan sebagai tambahan, jugaSTDIN
file biasa yang akan diproses oleh perintah.STDIN
dapat dilewati dengan pipa|
atau dengan memasukkan secara manual.Baca manual atau kode sumber. Dan jika Anda tidak menemukan apa pun yang Anda butuhkan, Anda dapat melakukan tes sederhana tetapi mungkin berbahaya:
Masukkan saja perintah yang membuat Anda penasaran, dengan argumen yang sudah Anda pahami, dan lihat apakah perintah itu berhenti (tidak terjadi apa-apa). Jika berhenti, sebenarnya menunggu STDIN (Anda dapat mencoba
cat
danecho
melihat perbedaannya). Anda mengetik secara manualCtrl-D
dan perintahnya maju (tampilkan hasil atau kesalahan) dan kembali. Perintah seperti itu membutuhkan STDIN dalam situasi itu (dengan argumen yang Anda berikan).Perintah yang sama mungkin tidak perlu STDIN dalam situasi yang berbeda (misalnya,
cat
menunggu STDIN tetapicat file.txt
tidak).sumber