มีวิธีทำ bash แสดงข้อความstderrในสีแดง?
function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }
งานได้กับทุบตีและ zsh ไม่สามารถเพิ่มสิ่งนี้เป็นคำตอบ b / c ชื่อเสียง
มีวิธีทำ bash แสดงข้อความstderrในสีแดง?
function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }
งานได้กับทุบตีและ zsh ไม่สามารถเพิ่มสิ่งนี้เป็นคำตอบ b / c ชื่อเสียง
คำตอบ:
command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)
>&2
ก่อนหน้า; done)
นี้เอาต์พุตที่มีไว้สำหรับ stderr จริงๆแล้วจะถูกเขียนไปยัง stderr มีประโยชน์ถ้าคุณต้องการบันทึกผลลัพธ์ปกติของโปรแกรม
tput
และสามารถอ่านได้ในความคิดของฉันเล็กน้อย:command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done)
IFS= read -r line
ควรช่วย แต่ไม่ ไม่แน่ใจว่าทำไม
วิธีที่ 1: ใช้การทดแทนกระบวนการ:
command 2> >(sed $'s,.*,\e[31m&\e[m,'>&2)
วิธีที่ 2: สร้างฟังก์ชันในสคริปต์ทุบตี:
color()(set -o pipefail;"$@" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1
ใช้แบบนี้:
$ color command
ทั้งสองวิธีจะแสดงคำสั่งเป็นstderr
สีแดง
อ่านต่อเพื่อดูคำอธิบายวิธีการทำงานของวิธีที่ 2 มีคุณสมบัติที่น่าสนใจที่แสดงโดยคำสั่งนี้
color()...
- สร้างฟังก์ชั่นทุบตีที่เรียกว่าสีset -o pipefail
- นี่คือตัวเลือกเชลล์ที่เก็บรักษาโค้ดส่งคืนข้อผิดพลาดของคำสั่งที่มีการส่งออกไพพ์ไปยังคำสั่งอื่น สิ่งนี้ทำใน subshell ซึ่งสร้างโดยวงเล็บเพื่อไม่ให้เปลี่ยนตัวเลือก pipefail ในเปลือกนอก "$@"
- ดำเนินการขัดแย้งกับฟังก์ชั่นเป็นคำสั่งใหม่ "$@"
เทียบเท่ากับ"$1" "$2" ...
2>&1
- เปลี่ยนเส้นทางstderr
ของคำสั่งการstdout
เพื่อที่จะกลายเป็นsed
stdin
>&3
- ชวเลขสำหรับ1>&3
นี้เปลี่ยนเส้นทางไปยังอธิบายไฟล์ใหม่ชั่วคราว stdout
ถูกส่งกลับเข้าไปในภายหลัง3
3
stdout
sed ...
- เนื่องจากการเปลี่ยนเส้นทางข้างต้นsed
's stdin
เป็นstderr
คำสั่งประหารชีวิต ฟังก์ชั่นคือการล้อมรอบแต่ละบรรทัดด้วยรหัสสี$'...'
โครงสร้างทุบตีที่ทำให้เข้าใจอักขระที่ใช้เครื่องหมายแบคสแลช.*
- จับคู่ทั้งบรรทัด\e[31m
- ลำดับ ANSI escape ที่ทำให้อักขระต่อไปนี้เป็นสีแดง&
- sed
อักขระแทนที่ที่ขยายเป็นสตริงที่ตรงกันทั้งหมด (ทั้งบรรทัดในกรณีนี้)\e[m
- ลำดับ ANSI escape ที่รีเซ็ตสี>&2
- ชวเลขสำหรับ1>&2
นี้เปลี่ยนเส้นทางsed
ของการstdout
stderr
3>&1
- เปลี่ยนเส้นทางบ่งแฟ้มชั่วคราว3
กลับเข้าstdout
มาzsh
หรือไม่?
zsh: color()(set -o pipefail;"$@" 2>&1 1>&3|sed $'s,.*,\e[31m&\e[m,'1>&2)3>&1
นอกจากนี้คุณยังสามารถดู stderred: https://github.com/sickill/stderred
.bashrc
) ขอบคุณนะ!
วิธีทุบตีในการทำให้stderrเป็นสีแดงอย่างถาวรคือการใช้ 'exec' เพื่อเปลี่ยนเส้นทางสตรีม เพิ่มสิ่งต่อไปนี้ใน bashrc ของคุณ:
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;'
ฉันโพสต์เมื่อก่อนหน้านี้: วิธีการตั้งค่าสีตัวอักษรสำหรับ STDOUT และ STDERR
source ~/.bashrc
สองครั้งด้วยสิ่งนี้ขั้วของฉันล็อคโดยทั่วไป
ฉันสร้างสคริปต์ตัวคลุมที่ใช้คำตอบของBalázsPozsárในการทุบตีบริสุทธิ์ บันทึกไว้ในคำสั่ง $ PATH และคำนำหน้าเพื่อเปลี่ยนสีเอาต์พุตของพวกเขา
#! / bin / ทุบตี ถ้า [$ 1 == "- ช่วยเหลือ"]; แล้วก็ echo "เรียกใช้งานคำสั่งและ colorize ข้อผิดพลาดทั้งหมดที่เกิดขึ้น" echo "ตัวอย่าง:` basename $ {0} `wget ... " echo "(c) o_O Tync, ICQ # 1227-700, Enjoy!" ออก 0 Fi # ไฟล์ชั่วคราวเพื่อตรวจจับข้อผิดพลาดทั้งหมด TMP_ERRS = $ (mktemp) # รันคำสั่ง "$ @" 2>> (ในขณะที่อ่านบรรทัด; ทำ echo -e "\ e [01; 31m $ line \ e [0m" | tee - เพิ่ม $ TMP_ERRS; เสร็จแล้ว) EXIT_CODE = $? # แสดงข้อผิดพลาดทั้งหมดอีกครั้ง ถ้า [-s "$ TMP_ERRS"]; แล้วก็ echo -e "\ n \ n \ n \ e [01; 31m === ข้อผิดพลาด === \ e [0m" cat $ TMP_ERRS Fi rm -f $ TMP_ERRS # เสร็จสิ้น ออกจาก $ EXIT_CODE
คุณสามารถใช้ฟังก์ชั่นเช่นนี้
#!/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
ฉันผนวก> & 2 เพื่อพิมพ์ไปยัง stderr
ฉันมีสคริปต์ของ O_o Tync เวอร์ชันแก้ไขเล็กน้อย ฉันต้องการทำให้ mods เหล่านี้สำหรับ OS X Lion และมันไม่สมบูรณ์แบบเพราะบางครั้งสคริปต์จะเสร็จสิ้นก่อนที่คำสั่ง wrapper จะทำ ฉันได้เพิ่มการนอนหลับ แต่ฉันแน่ใจว่ามีวิธีที่ดีกว่า
#!/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
วิธีนี้ใช้ได้ผลกับฉัน: https://superuser.com/questions/28869/immediately-tell-which-output-was-sent-to-stderr
ฉันได้ใส่ฟังก์ชั่นนี้ในของฉัน.bashrc
หรือ.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
}
ตัวอย่างเช่น:
$ rse cat non_existing_file.txt
จะให้ผลลัพธ์เป็นสีแดง
set -o pipefail;
ก่อน(eval
เพื่อเปลี่ยนรหัสออก
"
eval เพื่อรักษาช่องว่างในการขัดแย้ง
ใช้ xargs และ printf:
command 2> >(xargs -0 printf "\e[31m%s\e[m" >&2)
รุ่นที่ใช้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