Saya kira bash tidak akan pernah mewarnai keluarannya: beberapa program mungkin ingin menguraikan sesuatu, dan pewarnaan akan merusak data dengan urutan yang lolos. Aplikasi GUI harus menangani warna, saya kira.
kolypto
Menggabungkan Balázs Pozsár dan killdash9 memberikan hasil yang bagus: function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') } Bekerja untuk bash dan zsh. Tidak dapat menambahkan ini sebagai jawaban b / c reputasi.
Heinrich Hartmann
1
Saya menunggu jawaban yang memodifikasi bash untuk melakukan ini. Solusi di bawah ini benar - benar mengubah stderr dan bahkan mungkin mengurutkannya kembali stdout yang memecah hal-hal ketika urutan byte yang tepat dari stderr harus dipertahankan misalnya ketika perpipaan.
Bagus! Tapi saya heran jika ada cara untuk membuatnya :) permanen
kolypto
9
Tip yang bagus! Saran: Dengan menambahkan >&2tepat sebelumnya ; done), output yang dimaksudkan untuk stderr sebenarnya ditulis ke stderr. Itu membantu jika Anda ingin menangkap output normal dari program.
henko
8
Penggunaan berikut tput, dan sedikit lebih mudah dibaca menurut saya:command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done)
Stefan Lasiewski
2
Saya pikir menjalankan 2 proses tput untuk setiap jalur output tidak elegan sama sekali. Mungkin jika Anda akan menyimpan output dari perintah tput dalam variabel dan menggunakannya untuk setiap gema. Tetapi sekali lagi, keterbacaan tidak benar-benar lebih baik.
Balázs Pozsár
1
Solusi ini tidak mempertahankan spasi putih tapi saya suka karena singkatnya. IFS= read -r lineharus membantu tetapi tidak. Tidak yakin kenapa.
Kedua metode akan menampilkan perintah stderrberwarna merah.
Baca terus untuk penjelasan tentang cara kerja metode 2. Ada beberapa fitur menarik yang ditunjukkan oleh perintah ini.
color()... - Membuat fungsi bash yang disebut warna.
set -o pipefail- Ini adalah opsi shell yang mempertahankan kode pengembalian kesalahan dari suatu perintah yang outputnya disalurkan ke perintah lain. Ini dilakukan dalam subkulit, yang dibuat oleh tanda kurung, agar tidak mengubah opsi pipefail di kulit terluar.
"$@"- Menjalankan argumen ke fungsi sebagai perintah baru. "$@"setara dengan"$1" "$2" ...
2>&1- Pengalihan yang stderrperintah untuk stdoutsehingga menjadi sed's stdin.
>&3- Singkatan dari 1>&3, ini mengalihkan stdoutke deskriptor file sementara yang baru 3. 3akan dialihkan kembali ke stdoutnanti.
sed ...- Karena pengalihan atas, sed's stdinadalah stderrdari perintah dieksekusi. Fungsinya untuk mengelilingi setiap baris dengan kode warna.
$'...' Konstruksi bash yang menyebabkannya memahami karakter backslash-escape
.* - Cocok dengan seluruh baris.
\e[31m - Urutan escape ANSI yang menyebabkan karakter berikut menjadi merah
&- sedKarakter ganti yang mengembang ke seluruh string yang cocok (seluruh baris dalam kasus ini).
\e[m - Urutan escape ANSI yang mengatur ulang warna.
>&2- Singkatan untuk 1>&2, ini pengalihan sed's stdoutuntuk stderr.
3>&1- Mengarahkan deskriptor file sementara 3kembali ke stdout.
Mengapa Anda perlu melakukan semua pengalihan tambahan? sepertinya berlebihan
qodeninja
1
Apakah ada cara untuk membuatnya bekerja zsh?
Eyal Levin
1
ZSH tidak mengenali bentuk pengalihan steno. Hanya perlu dua lagi 1, yaitu:zsh: color()(set -o pipefail;"$@" 2>&1 1>&3|sed $'s,.*,\e[31m&\e[m,'1>&2)3>&1
Wow, utilitas ini luar biasa, satu-satunya hal yang diperlukan adalah memiliki repositori yang tepat yang menginstalnya untuk semua pengguna, dengan satu baris, tidak harus melakukan lebih banyak pekerjaan untuk mengaktifkannya.
sorin
Tampaknya berfungsi dengan baik ketika saya mengujinya dengan skrip build di terminal yang terpisah, tapi saya ragu untuk menggunakannya secara global .bashrc. Terimakasih Meskipun!
Joel Purra
2
Di OS X El Capitan, cara kerjanya (DYLD_INSERT_LIBRARY) "rusak" dalam biner sistem karena dilindungi oleh SIP. Jadi mungkin lebih baik menggunakan opsi bash yang diberikan dalam jawaban lain.
hmijail
1
@hmijail untuk MacOS silakan ikuti github.com/sickill/stderred/issues/60 sehingga kita dapat menemukan solusinya, sebagian sudah ada tetapi sedikit buggy.
Sorin
15
Cara bash membuat stderr merah secara permanen menggunakan 'exec' untuk mengarahkan aliran. Tambahkan yang berikut ke bashrc Anda:
Ini adalah jawaban terbaik sejauh ini; mudah diimplementasikan tanpa instalasi / memerlukan hak sudo, dan dapat digeneralisasi untuk semua perintah.
Luke Davis
1
Sayangnya ini tidak berjalan dengan baik dengan perintah chaining (command && nextCommand || errorHandlerCommand). Output kesalahan berjalan setelah output errorHandlerCommand.
carlin.scott
1
Demikian pula, jika saya source ~/.bashrcdua kali dengan ini, terminal saya pada dasarnya terkunci.
Dolph
@ Wolf: Di bashrc saya, saya dengan mudah menjaga ini dengan pernyataan if untuk mencegah kode ini dari reload. Kalau tidak, masalahnya adalah pengalihan 'exec 9> & 2' setelah pengalihan sudah terjadi. Mungkin mengubahnya ke konstanta jika Anda tahu di mana> 2 menunjuk pada awalnya.
Saya telah membuat skrip pembungkus yang mengimplementasikan jawaban Balázs Pozsár di bash murni. Simpan di $ PATH dan perintah awalan untuk mewarnai hasilnya.
#! / bin / bash
if [$ 1 == "--help"]; kemudian
echo "Menjalankan perintah dan mewarnai semua kesalahan yang terjadi"
echo "Contoh:` basename $ {0} `wget ..."
echo "(c) o_O Tync, ICQ # 1227-700, Selamat Menikmati!"
keluar 0
fi
# Temp file untuk menangkap semua kesalahan
TMP_ERRS = $ (mktemp)
# Jalankan perintah
"$ @" 2>> (saat membaca baris; lakukan gema -e "\ e [01; 31m $ baris \ e [0m" | tee --append $ TMP_ERRS; selesai)
EXIT_CODE = $?
# Tampilkan semua kesalahan lagi
if [-s "$ TMP_ERRS"]; kemudian
echo -e "\ n \ n \ n \ e [01; 31m === KESALAHAN === \ e [0m"
cat $ TMP_ERRS
fi
rm -f $ TMP_ERRS
# Selesai
keluar $ EXIT_CODE
Tidak mengatasi masalah. Anda belum memberikan cara untuk memisahkan stderr dari stdout, yang merupakan tujuan OP.
Jeremy Visser
1
Saya memiliki skrip O_o Tync versi yang sedikit dimodifikasi. Saya perlu membuat mod ini untuk OS X Lion dan itu tidak sempurna karena skrip terkadang selesai sebelum perintah yang dibungkus melakukannya. Saya sudah menambahkan tidur tapi saya yakin ada cara yang lebih baik.
#!/bin/bashif[ $1 =="--help"];then
echo "Executes a command and colorizes all errors occured"
echo "Example: `basename ${0}` wget ..."
echo "(c) o_O Tync, ICQ# 1227-700, Enjoy!"
exit 0fi# Temp file to catch all errors
TMP_ERRS=`mktemp /tmp/temperr.XXXXXX`|| exit 1# Execute command"$@"2>>(while read line;do echo -e "$(tput setaf 1)$line\n"| tee -a $TMP_ERRS;done)
EXIT_CODE=$?
sleep 1# Display all errors againif[-s "$TMP_ERRS"];then
echo -e "\n\n\n$(tput setaf 1) === ERRORS === "
cat $TMP_ERRS
else
echo "No errors collected in $TMP_ERRS"fi
rm -f $TMP_ERRS
# Finish
exit $EXIT_CODE
Saya telah menempatkan fungsi ini di .bashrcatau .zshrc:
# 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>&11>&22>&3| sed -e "s/^\(.*\)$/$(echo -en \\033)[31;1m\1$(echo -en \\033)[0m/")3>&11>&22>&3}
function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }
Bekerja untuk bash dan zsh. Tidak dapat menambahkan ini sebagai jawaban b / c reputasi.Jawaban:
sumber
>&2
tepat sebelumnya; done)
, output yang dimaksudkan untuk stderr sebenarnya ditulis ke stderr. Itu membantu jika Anda ingin menangkap output normal dari program.tput
, dan sedikit lebih mudah dibaca menurut saya:command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done)
IFS= read -r line
harus membantu tetapi tidak. Tidak yakin kenapa.Metode 1: Gunakan substitusi proses:
Metode 2: Buat fungsi dalam skrip bash:
Gunakan seperti ini:
Kedua metode akan menampilkan perintah
stderr
berwarna merah.Baca terus untuk penjelasan tentang cara kerja metode 2. Ada beberapa fitur menarik yang ditunjukkan oleh perintah ini.
color()...
- Membuat fungsi bash yang disebut warna.set -o pipefail
- Ini adalah opsi shell yang mempertahankan kode pengembalian kesalahan dari suatu perintah yang outputnya disalurkan ke perintah lain. Ini dilakukan dalam subkulit, yang dibuat oleh tanda kurung, agar tidak mengubah opsi pipefail di kulit terluar."$@"
- Menjalankan argumen ke fungsi sebagai perintah baru."$@"
setara dengan"$1" "$2" ...
2>&1
- Pengalihan yangstderr
perintah untukstdout
sehingga menjadised
'sstdin
.>&3
- Singkatan dari1>&3
, ini mengalihkanstdout
ke deskriptor file sementara yang baru3
.3
akan dialihkan kembali kestdout
nanti.sed ...
- Karena pengalihan atas,sed
'sstdin
adalahstderr
dari perintah dieksekusi. Fungsinya untuk mengelilingi setiap baris dengan kode warna.$'...'
Konstruksi bash yang menyebabkannya memahami karakter backslash-escape.*
- Cocok dengan seluruh baris.\e[31m
- Urutan escape ANSI yang menyebabkan karakter berikut menjadi merah&
-sed
Karakter ganti yang mengembang ke seluruh string yang cocok (seluruh baris dalam kasus ini).\e[m
- Urutan escape ANSI yang mengatur ulang warna.>&2
- Singkatan untuk1>&2
, ini pengalihansed
'sstdout
untukstderr
.3>&1
- Mengarahkan deskriptor file sementara3
kembali kestdout
.sumber
zsh
?zsh: color()(set -o pipefail;"$@" 2>&1 1>&3|sed $'s,.*,\e[31m&\e[m,'1>&2)3>&1
Anda juga dapat melihat stderred: https://github.com/sickill/stderred
sumber
.bashrc
. Terimakasih Meskipun!Cara bash membuat stderr merah secara permanen menggunakan 'exec' untuk mengarahkan aliran. Tambahkan yang berikut ke bashrc Anda:
Saya telah memposting ini sebelumnya: Cara mengatur warna font untuk STDOUT dan STDERR
sumber
source ~/.bashrc
dua kali dengan ini, terminal saya pada dasarnya terkunci.http://sourceforge.net/projects/hilite/
sumber
Saya telah membuat skrip pembungkus yang mengimplementasikan jawaban Balázs Pozsár di bash murni. Simpan di $ PATH dan perintah awalan untuk mewarnai hasilnya.
sumber
Anda dapat menggunakan fungsi seperti ini
Saya tambahkan> & 2 untuk mencetak ke stderr
sumber
Saya memiliki skrip O_o Tync versi yang sedikit dimodifikasi. Saya perlu membuat mod ini untuk OS X Lion dan itu tidak sempurna karena skrip terkadang selesai sebelum perintah yang dibungkus melakukannya. Saya sudah menambahkan tidur tapi saya yakin ada cara yang lebih baik.
sumber
Solusi ini bekerja untuk saya: https://superuser.com/questions/28869/immediately-tell-which-output-was-sent-to-stderr
Saya telah menempatkan fungsi ini di
.bashrc
atau.zshrc
:Lalu misalnya:
akan memberi saya output merah.
sumber
set -o pipefail;
sebelumnya(eval
untuk kode keluar redirect"
ke eval untuk menghemat spasi dalam argumenmenggunakan xargs dan printf:
sumber
versi menggunakan fifos
sumber