Apakah ada cara untuk membuat bash menampilkan pesan stderr dalam warna merah?
function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }
Bekerja untuk bash dan zsh. Tidak dapat menambahkan ini sebagai jawaban b / c reputasi.
Apakah ada cara untuk membuat bash menampilkan pesan stderr dalam warna merah?
function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }
Bekerja untuk bash dan zsh. Tidak dapat menambahkan ini sebagai jawaban b / c reputasi.
Jawaban:
command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)
>&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:
command 2> >(sed $'s,.*,\e[31m&\e[m,'>&2)
Metode 2: Buat fungsi dalam skrip bash:
color()(set -o pipefail;"$@" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1
Gunakan seperti ini:
$ color command
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 yang stderr
perintah untuk stdout
sehingga menjadi sed
's stdin
.>&3
- Singkatan dari 1>&3
, ini mengalihkan stdout
ke deskriptor file sementara yang baru 3
. 3
akan dialihkan kembali ke stdout
nanti.sed ...
- Karena pengalihan atas, sed
's stdin
adalah stderr
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 untuk 1>&2
, ini pengalihan sed
's stdout
untuk stderr
.3>&1
- Mengarahkan deskriptor file sementara 3
kembali ke stdout
.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
.bashrc
. Terimakasih Meskipun!
Cara bash membuat stderr merah secara permanen menggunakan 'exec' untuk mengarahkan aliran. Tambahkan yang berikut ke bashrc Anda:
exec 9>&2
exec 8> >(
while IFS='' read -r line || [ -n "$line" ]; do
echo -e "\033[31m${line}\033[0m"
done
)
function undirect(){ exec 2>&9; }
function redirect(){ exec 2>&8; }
trap "redirect;" DEBUG
PROMPT_COMMAND='undirect;'
Saya telah memposting ini sebelumnya: Cara mengatur warna font untuk STDOUT dan STDERR
source ~/.bashrc
dua kali dengan ini, terminal saya pada dasarnya terkunci.
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
Anda dapat menggunakan fungsi seperti ini
#!/bin/sh
color() {
printf '\033[%sm%s\033[m\n' "$@"
# usage color "31;5" "string"
# 0 default
# 5 blink, 1 strong, 4 underlined
# fg: 31 red, 32 green, 33 yellow, 34 blue, 35 purple, 36 cyan, 37 white
# bg: 40 black, 41 red, 44 blue, 45 purple
}
string="Hello world!"
color '31;1' "$string" >&2
Saya tambahkan> & 2 untuk mencetak ke stderr
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/bash
if [ $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 0
fi
# 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 again
if [ -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
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
:
# 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
}
Lalu misalnya:
$ rse cat non_existing_file.txt
akan memberi saya output merah.
set -o pipefail;
sebelumnya (eval
untuk kode keluar redirect
"
ke eval untuk menghemat spasi dalam argumen
menggunakan xargs dan printf:
command 2> >(xargs -0 printf "\e[31m%s\e[m" >&2)
versi menggunakan fifos
mkfifo errs
stdbuf -o0 -e0 -i0 grep . foo | while read line; do echo -e "\e[01;31m$line \e[0m" >&2; done &
stdbuf -o0 -e0 -i0 sh $script 2>errs