Segera beri tahu output mana yang dikirim ke stderr

8

Saat mengotomatiskan tugas, masuk akal untuk mengujinya terlebih dahulu secara manual. Akan sangat membantu, jika ada data yang pergi ke stderr langsung dapat dikenali, dan dapat dibedakan dari data yang akan stdout, dan untuk memiliki semua output bersama sehingga jelas apa urutan kejadiannya.

Satu sentuhan terakhir yang akan menyenangkan adalah jika, saat keluar dari program, ia mencetak kode pengembaliannya.

Semua hal ini akan membantu dalam mengotomatisasi. Ya, saya bisa mengulangi kode kembali ketika sebuah program selesai, dan ya, saya bisa mengarahkan stdout dan stderr; apa yang saya benar-benar suka itu beberapa shell, script, atau redirector yang mudah digunakan yang menunjukkan stdout dalam warna hitam, menunjukkan stderr disisipkan dengan warna merah, dan mencetak kode keluar di akhir.

Apakah ada binatang seperti itu? [Jika itu penting, saya menggunakan Bash 3.2 di Mac OS X].


Pembaruan : Maaf sudah berbulan-bulan sejak saya melihat ini. Saya datang dengan skrip tes sederhana:

#!/usr/bin/env python
import sys

print "this is stdout"
print >> sys.stderr, "this is stderr"
print "this is stdout again"

Dalam pengujian saya (dan mungkin karena cara buffered), rse dan hilite menampilkan semuanya dari stdout dan kemudian semuanya dari stderr. Metode fifo mendapatkan urutan yang benar tetapi tampaknya mewarnai semua yang mengikuti garis stderr. ind mengeluh tentang garis stdin dan stderr saya, dan kemudian menempatkan output dari stderr terakhir.

Sebagian besar solusi ini bisa diterapkan, karena tidak biasa hanya untuk output terakhir pergi ke stderr, tapi tetap saja, akan menyenangkan untuk memiliki sesuatu yang bekerja sedikit lebih baik.

Clinton Blackmore
sumber
Jika Anda malas (atau memiliki jari-jari yang sakit) seperti saya, Anda dapat mengambil subkulit dengan solusi di bawah ini (mis. Rse zsh) dan sekarang semua perintah mewarnai stderr.
bias

Jawaban:

3

Anda juga dapat melihat stderred: https://github.com/sickill/stderred

sickill
sumber
Sayangnya, stderred break "open" dan "mvim" untuk pengguna Mac seperti OP.
AlcubierreDrive
Ini bekerja dengan sangat baik, dan mendapatkan urutan output dengan cara yang benar karena cara kerjanya. Atur sekali, dan nyalakan di profil Anda, dan Anda mendapatkan pesan merah setiap kali stderr ditulis.
Clinton Blackmore
1
@ JonRodriguez, bagi saya tampaknya masalah dengan perintah "terbuka" telah diperbaiki .
Clinton Blackmore
9

Saya baru saja menemukan metode gila yang melibatkan FIFO.

$ mkfifo foo
$ grep --color . foo &
$ your_command 2>foo

Jika Anda ingin output stderr terpisah, Anda dapat membuka dua shell terpisah dan menjalankan " grep --color . foo" di satu tanpa &, kemudian jalankan perintah di yang lain (masih dengan 2>foo). Anda akan mendapatkan stderr di yang grepsatu dan stdout di yang utama.

Ini berfungsi karena output stderr dialihkan melalui FIFO ke grep --color, yang warna defaultnya merah (setidaknya untuk saya). Setelah selesai, cukup rmFIFO ( rm foo).

Peringatan : Saya benar-benar tidak yakin bagaimana ini akan menangani pesanan keluaran, Anda harus mengujinya.

jtbandes
sumber
Itu cukup bagus.
Clinton Blackmore
7

Ya, ini mungkin. Lihatlah bagian "Jadikan STDERR merah" di situs ini untuk contoh yang berfungsi.

Kode dasarnya adalah ini

# Red STDERR
# rse <command string>
function rse()
{
    # We need to wrap each phrase of the command in quotes to preserve arguments that contain whitespace
    # Execute the command, swap STDOUT and STDERR, colour STDOUT, swap back
    ((eval $(for phrase in "$@"; do echo -n "'$phrase' "; done)) 3>&1 1>&2 2>&3 | sed -e "s/^\(.*\)$/$(echo -en \\033)[31;1m\1$(echo -en \\033)[0m/") 3>&1 1>&2 2>&3
}

Penjelasan singkat diberikan dalam fungsi itu sendiri. Apa yang dilakukan adalah memindahkan STDOUT dan STDERR tentang, jadi sed mendapatkan STDERR dalam 1, warna itu, dan kemudian menukarnya kembali. Pikirkan aliran file 3 sebagai variabel temp di sini.

Panggilannya cukup sederhana

rse commands

Namun, doa tertentu tidak akan berfungsi seperti yang diharapkan; peringatan semua disediakan di halaman yang terhubung.

Btw, saya pikir itu juga mungkin untuk datang dengan solusi bentuk

commands | rse 

di mana rse akan mewarnai output.

Saya juga menemukan proyek hilite ini yang tampaknya melakukan ini. Saya belum mencobanya, tapi mungkin itu yang Anda cari.

hilite adalah utilitas kecil yang mengeksekusi perintah yang Anda tentukan, menyoroti apa pun yang dicetak ke stderr. Ini dirancang terutama untuk digunakan dengan build, untuk membuat peringatan dan kesalahan menonjol seperti klise yang menyakitkan.

Proyek terkait lainnya:


sumber
Rse dan hilite cukup dekat dengan apa yang saya inginkan.
Clinton Blackmore
1

Program lain adalah ind:

http: // www.habets.pp.se/synscan/programs.php?prog=ind (Anda harus merakit sendiri tautannya, saya tidak punya cukup poin untuk lebih dari satu per jawaban). Ada screenshot dan bahkan screencast di sana.

Ini menjalankan subproses dalam pty, yang lain mungkin tidak. Ini bisa menjadi masalah di mana urutan penting (sering kali demikian), karena stderr segera dibilas di terminal dan stdout sepenuhnya buffer ketika itu bukan tty.

Untuk penjelasan lengkap, lihat ini: http://blog.habets.pp.se/2008/06/Buffering-in-pipes

Juga, ind bekerja dengan program interaktif dan karakter kontrol. Bash bekerja seperti biasa ketika dimulai dengan "ind bash -i".

Ini bisa berfungsi untuk memberi Anda warna sambil mempertahankan Ctrl-P et.al.

ind -P $(echo -ne '\033[31;1m') -p $(echo -ne '\033[0m') bash -i
Thomas
sumber
1

Ini ada banyak respons untuk menyoroti keluaran stderr. Saya hanya dapat menambahkan satu cukup mudah - dalam satu baris, yang Anda lampirkan ke perintah:

command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m"; done)

Tetapi Anda harus menambahkan ini setelah perintah setiap kali.

Saya, secara pribadi, menyukai kemungkinan yang disebutkan oleh @nagul, fungsi rse ditambahkan ke bashrc.

Tetapi saya ingin menambahkan solusi untuk mencetak kode keluar. Anda dapat menambahkan nilai ini ke awal baris bash prompt Anda:

hostname$ command
  Some error occurred. Returned exit code.
EC hostname$

Di mana EC adalah kode keluar dari perintah.

Saya sudah mengatur di jalan, bahwa ketika kode keluar adalah 0, itu tidak akan dicetak, tetapi nilai lainnya dicetak sebelum prompt berikutnya dalam warna merah.

Seluruh trik dilakukan di ~ / .bashrc:

my_prompt() {
 EXITSTATUS="$?"
 RED="\[\033[1;31m\]"
 OFF="\[\033[m\]"

PROMPT="${debian_chroot:+($debian_chroot)}\h \$ "

if [ "${EXITSTATUS}" -eq 0 ]; then
   PS1="${PROMPT}"
else
   PS1="${RED}$EXITSTATUS${OFF} ${PROMPT}"
fi
}

PROMPT_COMMAND=my_prompt

Baris prompt secara default ditentukan oleh variabel PS1. Salin apa pun yang Anda miliki di sini ke PROMPT variabel dan kemudian buat variabel PS1 dengan atau tanpa kode keluar.

Bash akan menampilkan informasi dalam variabel PS1 di prompt.

srnka
sumber
Ini persis apa yang saya cari, terima kasih!
Dylon
1

ada annotate-outpututilitas ( devscriptspaket Debian), jika Anda ingin melakukannya tanpa warna

$ annotate-output /tmp/test.py    
14:24:57 I: Started /tmp/test.py
14:24:57 E: this is stderr
14:24:57 O: this is stdout
14:24:57 O: this is stdout again
14:24:57 I: Finished with exitcode 0
mykhal
sumber