Bagaimana cara memasang stdout sambil menyimpannya di layar? (dan bukan ke file output)

234

Saya ingin menyalurkan output standar suatu program sambil menyimpannya di layar.

Dengan contoh sederhana ( echogunakan di sini hanya untuk tujuan ilustrasi):

$ echo 'ee' | foo
ee <- output yang ingin saya lihat

Saya tahu tee bisa menyalin stdout ke file tetapi bukan itu yang saya inginkan.
$ echo 'ee' | tee output.txt | foo

Saya mencoba
$ echo 'ee' | tee /dev/stdout | footetapi tidak berhasil karena tee output /dev/stdoutdisalurkan kefoo

gentooboontoo
sumber
6
Perhatikan bahwa itu echo 'ee' | tee /dev/stderrberfungsi, jadi jika persyaratan "di layar" Anda dipenuhi oleh stderr juga, itu bisa dilakukan.
nh2

Jawaban:

344

Berikut ini adalah solusi yang berfungsi pada implementasi Unix / Linux, dengan asumsi itu mengikuti POSIXstandar. Ini berfungsi pada beberapa lingkungan non Unix cygwinjuga.

echo 'ee' | tee /dev/tty | foo

Referensi: Spesifikasi Basis Grup Terbuka Edisi 7 IEEE Std 1003.1, 2013 Edisi, §10.1 :

/ dev / tty

Terkait dengan kelompok proses proses itu, jika ada. Ini berguna untuk program atau prosedur shell yang ingin memastikan penulisan pesan atau membaca data dari terminal tidak peduli bagaimana output telah diarahkan. Itu juga dapat digunakan untuk aplikasi yang menuntut nama file untuk keluaran, ketika keluaran yang diinginkan diinginkan dan itu melelahkan untuk mengetahui terminal apa yang sedang digunakan. Dalam setiap proses, sinonim untuk terminal pengendali

Beberapa lingkungan seperti Google Colab telah dilaporkan tidak menerapkan /dev/ttysementara masih memiliki ttyperintah mereka mengembalikan perangkat yang dapat digunakan. Berikut ini solusinya:

tty=$(tty)
echo 'ee' | tee $tty | foo

atau dengan cangkang Bourne kuno:

tty=`tty`
echo 'ee' | tee $tty | foo
Jlliagre
sumber
5
@static_rtti Mengapa Anda mengabaikan tahun demi tahun balasan saya untuk komentar Anda?
jlliagre
1
@ PaulBissex /dev/ttyadalah perangkat Unix wajib. Apakah Anda menjalankan di penjara BSD?
jlliagre
1
@ PaulBissex Baik bug implementasi atau bug konfigurasi. Apakah / dev dipasang? Apa yang menunjukkan "ls-l / dev / tty / dev / tty * / dev"? Lihat lists.freebsd.org/pipermail/freebsd-bugs/2012-November/... forums.freebsd.org/threads/...
jlliagre
1
Dan Anda dapat kaskade teeseperti ini: cat some.log | tee /dev/tty | tee -a other.log | grep -i 'foo' >> foo.logke 1) mendapatkan semuanya ke konsol, 2) mendapatkan semuanya ditambahkan ke file lain, 3) mendapatkan foobaris ke file yang berbeda.
Jesse Chisholm
1
Google Colab tidak memiliki /dev/tty, tetapi output ttydapat digunakan.
Tom Hale
69

Hal lain untuk dicoba adalah:

echo 'ee' | tee >(foo)

Ini >(foo)adalah proses substitusi .

bmk
sumber
1
bagaimana jika saya ingin menyalurkan output foo ke bar lain?
Jack Tang
3
@ JackTang - Saya pikir setiap pemipaan lebih lanjut pada output fooharus menjadi bagian dari proses substitusi. Ini sebuah contoh:echo 'ee' | tee file.txt >(wc -c | tr -d ' ')
Nick Chammas
1
Ini adalah solusi bagi saya di FreeBSD (no / dev / tty)
Paul Bissex
9
@ Nick Chammas, Untuk menjaga pipa normal, Anda dapat menukar output dari tee: echo 'ee' | tee >(cat) | foo | bar.
Vaelus
18

Akses ke "/ dev / stdout" ditolak pada beberapa sistem, tetapi akses ke terminal pengguna diberikan oleh "/ dev / tty". Menggunakan "wc" untuk "foo", contoh di atas berfungsi OK (di linux, OSX, dll.) Sebagai:

% echo 'Hi' | tee /dev/tty | wc Hi 1 1 3

Untuk menambahkan hitungan di bagian bawah daftar file yang cocok, saya menggunakan sesuatu seperti:
% ls [A-J]* | tee /dev/tty | wc -l

Untuk menghindari harus mengingat semua ini, saya mendefinisikan alias:
% alias t tee /dev/tty
% alias wcl wc -l

jadi saya bisa mengatakan:
% ls [A-J]* | t | wcl


POSTSCRIPT: Untuk set yang lebih muda, yang mungkin mengecilkan pengucapannya sebagai "titty", saya dapat menambahkan bahwa "tty" pernah menjadi singkatan umum untuk terminal "teletype", yang menggunakan gulungan kertas kuning dan memiliki kunci bundar yang sering macet.

pengguna51527
sumber
17

Mencoba:

$ echo 'ee' | tee /dev/stderr | foo

Jika menggunakan stderr adalah suatu pilihan, tentu saja.

Jan
sumber
8

pertama-tama Anda harus mencari tahu terminal yang terkait dengan layar Anda (atau layar mana pun yang Anda inginkan untuk menampilkannya):

tty

maka Anda dapat mem-tee output ke terminal itu dan mengirimkan salinan lainnya melalui program foo Anda:

echo ee | tee /dev/pty/2 | foo
Michael Martinez
sumber
1
oneliner: t = $ (tty) echo ee | tee $ t | foo | bar
Jack Tang
5
@ JackTang Itu memang lebih baik tetapi ttidak berguna. Anda dapat menggunakan echo ee | tee $(tty) | footetapi masih memiliki perintah tidak berguna ( tty), mengingat fakta itu /dev/ttyhanya berfungsi.
jlliagre