it-swarm-vi.tech

bash: in stderr màu đỏ

Có cách nào để hiển thị bash stderr tin nhắn màu đỏ?

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

Phương pháp 1: Sử dụng thay thế quá trình:

command 2> >(sed $'s,.*,\e[31m&\e[m,'>&2)

Phương pháp 2: Tạo một hàm trong tập lệnh bash:

color()(set -o pipefail;"[email protected]" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1

Sử dụng nó như thế này:

$ color command

Cả hai phương thức sẽ hiển thị lệnh stderr màu đỏ.

Tiếp tục đọc để giải thích về cách thức hoạt động của phương pháp 2. Có một số tính năng thú vị được thể hiện bằng lệnh này.

  • color()... - Tạo một hàm bash gọi là color.
  • set -o pipefail - Đây là tùy chọn Shell bảo tồn mã trả về lỗi của một lệnh có đầu ra được dẫn vào một lệnh khác. Điều này được thực hiện trong một lớp con, được tạo bởi dấu ngoặc đơn, để không thay đổi tùy chọn đường ống trong Shell bên ngoài.
  • "[email protected]" - Thực hiện các đối số cho hàm dưới dạng một lệnh mới. "[email protected]" Tương đương với "$1" "$2" ...
  • 2>&1 - Chuyển hướng stderr của lệnh thành stdout để nó trở thành sed 's stdin.
  • >&3 - Viết tắt cho 1>&3, Điều này chuyển hướng stdout đến một bộ mô tả tệp tạm thời mới 3. 3 Sẽ được chuyển trở lại vào stdout sau đó.
  • sed ... - Do các chuyển hướng ở trên, sed 's stdinstderr của lệnh được thực thi. Chức năng của nó là bao quanh mỗi dòng với mã màu.
  • $'...' Cấu trúc bash khiến nó hiểu các ký tự thoát dấu gạch chéo ngược
  • .* - Phù hợp với toàn bộ dòng.
  • \e[31m - Chuỗi thoát ANSI khiến các ký tự sau có màu đỏ
  • & - Ký tự thay thế sed mở rộng ra toàn bộ chuỗi khớp (toàn bộ dòng trong trường hợp này).
  • \e[m - Trình tự thoát ANSI đặt lại màu.
  • >&2 - Viết tắt cho 1>&2, Điều này chuyển hướng sed 's stdout đến stderr.
  • 3>&1 - Chuyển hướng mô tả tệp tạm thời 3 Trở lại stdout.
93
killdash9

Bạn cũng có thể xem stderred: https://github.com/sickill/stderred

29
sickill

Cách bash tạo stderr màu đỏ vĩnh viễn là sử dụng 'exec' để chuyển hướng luồng. Thêm phần sau vào bashrc của bạn:

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;'

Tôi đã đăng trên này trước đây: Cách đặt màu phông chữ cho STDOUT và STDERR

17
gospes
14
quaie

Tôi đã tạo một kịch bản bao bọc thực hiện câu trả lời của Balázs Pozsár trong bash thuần túy. Lưu nó trong các lệnh $ PATH và tiền tố của bạn để tô màu đầu ra của chúng.

[.__.] [.__.] #!/bin/bash [.__.] [.__.] nếu [$ 1 == "- trợ giúp"]; sau đó [.__.] echo "Thực thi một lệnh và tô màu tất cả các lỗi xảy ra" [.__.] echo "Ví dụ:` basename $ {0} `wget ..." [.__.] echo "(c) o_O Tync , ICQ # 1227-700, Hãy tận hưởng! "[.__.] Thoát 0 [.__.] Fi [.__.] [.__.] # Tập tin tạm thời để bắt tất cả các lỗi [.__.] TMP_ERRS = $ (mktemp ) [.__.] [.__.] # Thực thi lệnh [.__.] "$ @" 2 >> (trong khi đọc dòng; làm echo -e "\ e [01; 31m $ line\e [0m" | tee --append $ TMP_ERRS; xong) [.__.] EXIT_CODE = $? [.__.] [.__.] # Hiển thị lại tất cả các lỗi [.__.] nếu [-s "$ TMP_ERRS"]; sau đó [.__.] echo -e "\ n\n\n\e [01; 31m === LRI ===\e [0m" [.__.] cat $ TMP_ERRS [.__.] fi 
 rm -f $ TMP_ERRS [.__.] [.__.] # Kết thúc [.__.] thoát $ EXIT_CODE [.__.] [.__.]
7
kolypto

Bạn có thể sử dụng một chức năng như thế này


 #!/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
</ mã>

Tôi chắp thêm> & 2 để in lên stderr

3
Ali Mezgani

Giải pháp này hiệu quả với tôi: https://superuser.com/questions/28869/immediately-tell-which-output-was-sent-to-stderr

Tôi đã đặt chức năng này trong .bashrc hoặc là .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 "[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
}

Sau đó, ví dụ:

$ rse cat non_existing_file.txt

sẽ cho tôi một đầu ra màu đỏ.

1
Eyal Levin

sử dụng xargs và printf:

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

Tôi có một phiên bản sửa đổi một chút của tập lệnh của O_o Tync. Tôi cần phải tạo các mod này cho OS X Lion và nó không hoàn hảo vì tập lệnh đôi khi hoàn thành trước khi lệnh được gói. Tôi đã thêm một giấc ngủ nhưng tôi chắc chắn có một cách tốt hơn.

#!/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

một phiên bản sử dụng 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