it-swarm-id.com

bash: cetak stderr dalam warna merah

Apakah ada cara untuk membuat tampilan bash stderr pesan berwarna merah?

124
kolypto
command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)
103
Balázs Pozsár

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;"[email protected]" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1

Gunakan seperti ini:

$ color command

Kedua metode akan menampilkan perintah stderr dalam warna 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 hasilnya disalurkan ke perintah lain. Ini dilakukan dalam subkulit, yang dibuat oleh tanda kurung, agar tidak mengubah opsi pipefail di Shell luar.
  • "[email protected]" - Menjalankan argumen ke fungsi sebagai perintah baru. "[email protected]" Setara dengan "$1" "$2" ...
  • 2>&1 - Mengarahkan stderr dari perintah ke stdout sehingga menjadi sed 's stdin.
  • >&3 - Singkatan dari 1>&3, Ini mengalihkan stdout ke deskriptor file sementara baru 3. 3 Akan dialihkan kembali ke stdout nanti.
  • sed ... - Karena pengalihan di atas, sed's stdin adalah stderr dari perintah yang 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 mengganti karakter yang diperluas ke seluruh string yang cocok (seluruh baris dalam kasus ini).
  • \e[m - Urutan escape ANSI yang mengatur ulang warna.
  • >&2 - Singkatan dari 1>&2, Ini mengarahkan ulang sed 's stdout ke stderr.
  • 3>&1 - Mengarahkan deskriptor file sementara 3 Kembali ke stdout.
93
killdash9

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

29
sickill

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

17
gospes
14
quaie

Saya telah membuat skrip pembungkus yang mengimplementasikan jawaban Balázs Pozsár di bash murni. Simpan di $ PATH Anda dan awalan perintah untuk mewarnai hasilnya.

 
 #!/bin/bash 
 
 jika [$ 1 == "--help"]; lalu 
 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 echo -e "\ e [01; 31m $ line\e [0m" | tee - tambahkan $ TMP_ERRS; selesai) 
 EXIT_CODE = $? 
 [Tampilkan semua kesalahan lagi 
 jika [-s "$ TMP_ERRS"]; lalu 
 echo -e "\ n\n\n\e [01; 31m === KESALAHAN ===\e [0m" 
 cat $ TMP_ERRS 
 fi 
 rm -f $ TMP_ERRS 
 
 # Selesai 
 keluar $ EXIT_CODE 
 
7
kolypto

Anda dapat menggunakan fungsi seperti ini


 #!/bin/sh

color() {
      printf '\033[%sm%s\033[m\n' "[email protected]"
      # 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
</code>

Saya tambahkan> & 2 untuk mencetak ke stderr

3
Ali Mezgani

Solusi ini bekerja untuk saya: https://superuser.com/questions/28869/immediately-tell-which-output-was-sent-to-stderr

Saya telah meletakkan fungsi ini di .bashrc Atau .zshrc Saya:

# 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 "[email protected]"; 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.

1
Eyal Levin

menggunakan xargs dan printf:

command 2> >(xargs -0 printf "\e[31m%s\e[m" >&2)
1
Carlos Barcellos

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
   "[email protected]" 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
1
Cliff

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
0
untore