Apakah mungkin untuk mengarahkan output suatu perintah ke lebih dari satu perintah?

21

Sejauh yang saya tahu, saya dapat menggunakan perintah tee untuk membagi output standar ke layar dan file lebih lanjut:

command -option1 -option2 argument | tee file1 file2 file3 

Apakah mungkin untuk mengarahkan output ke perintah daripada file menggunakan tee, sehingga saya secara teoritis bisa membuat rantai perintah?

Abdul Al Hazred
sumber
3
Jelaskan apa yang Anda maksud dengan "sinyal keluaran" dan jelaskan apa yang Anda maksud dengan menciptakan "jaringan perintah".
Janis
di linux setiap perintah memiliki satu input dan dua output. mereka diberi label dengan 0 (untuk input), 1 (untuk output) dan 2 (untuk output kesalahan). Saya sedang memikirkan 1 ketika saya mengatakan "sinyal keluaran" karena saya membaca bahwa perintah tee hanya membagi keluaran yang berlabel 1. Ketika saya mengatakan "jaringan perintah" saya tidak terlalu teknis, saya tidak yakin bagaimana jaringan didefinisikan dengan benar dari sudut pandang matematis, tetapi saya hanya memikirkan sebatang pohon perintah yang secara tipologis berbicara, sehingga beberapa perintah dapat menjadi orangtua untuk lebih dari satu perintah anak.
Abdul Al Hazred
Terima kasih atas klarifikasi Anda. Tolong jangan gunakan sinyal kata karena memiliki arti khusus di Unix, dan istilah itu sangat menyesatkan dalam konteks ini. Terima kasih lagi.
Janis
Pada baris perintah, masukkan sinyal man -k untuk mempelajari makna khusus konsep kunci ini di UNIX dan Linux. man kill akan menjadi halaman yang bagus untuk memulai.
Rob
Juga, banyak orang menyebut stdin stdout dan stderr sebagai input atau output 'stream'. Ada seperti sungai-sungai kecil data karenanya sebuah aliran. Anda benar untuk bergulat dengan kata untuk menggambarkan mereka secara kolektif tetapi sinyal hanyalah kata yang salah.
Rob

Jawaban:

25

Anda bisa menggunakan pipa bernama ( http://linux.die.net/man/1/mkfifo ) pada baris perintah teedan memiliki perintah membaca pada pipa bernama.

mkfifo /tmp/data0 /tmp/data1 /tmp/data2
cmd0 < /tmp/data0 & cmd1 < /tmp/data1 & cmd2 < /tmp/data2 &
command -option1 -option2 argument | tee /tmp/data0 /tmp/data1 /tmp/data2

Ketika commandselesai, teeakan menutup pipa bernama, yang akan memberi sinyal EOF (baca 0 byte) pada masing-masing /tmp/dataNyang biasanya akan menghentikan cmdNproses. Contoh nyata:

$ mkfifo /tmp/data0 /tmp/data1 /tmp/data2
$ wc -l < /tmp/data0 & wc -w < /tmp/data1 & wc -c < /tmp/data2 &
$ tee /tmp/data0 /tmp/data1 /tmp/data2 < /etc/passwd >/dev/null
$ 61
1974
37

Karena proses latar belakang, shell mengembalikan prompt sebelum output program. Ketiga contoh wcdiakhiri secara normal.

Arcege
sumber
1
Di bash , Anda dapat menyimpan banyak pengetikan dengan aman /tmp/data/{0,1,2}. Kemudian lagi, dalam bash Anda bisa menggunakan proses substitusi dan lewati mkfifoseluruhnya
Tobias Kienzler
2
Mungkin ingin mengubah / dev / data0 ke / tmp / data0. Juga, terima kasih telah menjawab pertanyaan dengan cara agnostik shell. Itu lebih bermanfaat daripada menganggap semua orang menggunakan bash.
abonet
15

Jika saya mengerti dengan benar, Anda mencari yang setara tee file1 file2 file3, tetapi daripada menulis data yang sama ke tiga file file1, file2dan file3, Anda ingin menyalurkan data yang sama ke dalam tiga perintah cmd1, cmd2dan cmd3, yaitu

… | ??? cmd1 cmd2 cmd3

harus setara dengan

… | cmd1 &
… | cmd2 &
… | cmd3 &

kecuali itu hanya akan dieksekusi sekali.

Ada dua cara untuk melakukan itu.

Ksh93, substitusi proses dukungan bash dan zsh . Ini adalah generalisasi dari pipa yang memungkinkan argumen dari suatu perintah menjadi file yang, ketika ditulis untuk, meneruskan data sebagai input ke suatu perintah (ada juga varian input yang, ketika dibaca dari, memperoleh output data dengan suatu perintah) . Itu adalah,

echo hello | tee >(cmd1)

mencetak helloke output standar dan selain itu dijalankan cmd1dengan helloinput.

Jadi misalnya, jika Anda ingin menduplikasi input somecommanddan meneruskannya ke keduanya cmd1dan cmd2, Anda bisa menggunakannya

somecommand | tee >(cmd1) | cmd2

Jika shell Anda tidak mendukung substitusi proses, Anda dapat menggunakan pipa bernama. Lihat jawaban Arcege untuk cara kerjanya. Pipa yang dinamai kurang nyaman daripada substitusi proses karena Anda harus membuatnya dan menghapusnya, dan memulai dan menyinkronkan proses secara manual. Mereka memiliki keuntungan menjadi sepenuhnya portabel, sedangkan tidak semua shell mendukung proses penggantian. Mereka juga dapat digunakan dalam skenario selain yang proses substitusi adalah untuk.

Di bawah tenda, pada beberapa sistem, proses penggantian menggunakan pipa bernama secara internal. Pada sebagian besar sistem, ini bergantung pada file bernama yang mewakili deskriptor file .

Gilles 'SANGAT berhenti menjadi jahat'
sumber
5
Lihat juga peedari moreutils.
Stéphane Chazelas
Perhatikan bahwa substitusi proses diperkenalkan oleh ksh88.
Stéphane Chazelas
6

Setidaknya dalam Anda dapat melewati mkfifomenggunakan subtitusi proses:

command -option1 -option2 argument | tee >(cmd1) >(cmd2) >(cmd3)

atau untuk mengadopsi contoh Arcege

tee >(wc -l) >(wc -w) >(wc -c) < /etc/passwd >/dev/null
Tobias Kienzler
sumber