Bash脚本自定义脚本中的stdout和stderr



我想在install.sh中执行一些脚本,看起来像:

#!/bin/bash
./script1.sh
./script2.sh
./script3.sh
...

它执行一堆脚本,所以我想通过颜色(绿色表示stdout,红色表示stderr(以及输出来自哪里来区分stdout和stderr。

我想要的输出格式是:

script1.sh: Hello                 # in green color (stdout)
script2.sh: Cannot read a file.   # in red color (stderr)

我的目标是以脚本的形式打印输出,格式为:

{script_name}: {green_if_stdout, red_if_stderr}

我不想编辑所有脚本中的每一个命令。

是否有任何方法可以覆盖(或自定义(脚本中的所有stdout和stderr输出?

#!/bin/bash
override_stdout_and_stderr
echo "Start"    # It also prints as green color
./script1.sh
./script2.sh
./script3.sh
...
restore_if_needed

您询问了如何为所有stdout和stderr着色,并在所有行前面加上脚本名称。

在下面的回答中,使用重定向将stdout发送到一个进程,将stderr发送到另一个进程。这要归功于如何重定向stderr。

使用awk在输入的输出前面加上所需的颜色,红色或绿色,然后打印每一行输入,并在打印完成后清除颜色设置。

#!/bin/bash
function colorize()
{
"$@" 2> >( awk '{ printf "'$1':""33[0;31m" $0 "33[0mn"}' ) 
1> >( awk '{ printf "'$1':""33[0;32m" $0 "33[0mn"}' )
}
colorize ./script1.sh
#!/bin/sh
# script1.sh
echo "Hello GREEN"
>&2 echo "Hello RED"

预期输出类似于此命令。

printf 'script1.sh:33[0;32mHello GREEN33[0mnscript1.sh:33[0;31mHello RED33[0mn'

使用read代替awk:

#!/bin/bash
function greenchar()
{
while read ln ; do
printf "$1:33[0;32m${ln}33[0;0mn" >&1
done
}
function redchar()
{
while read ln ; do
printf "$1:33[0;31m${ln}33[0;0mn" >&2
done
}
function colorize()
{
$* 2> >( redchar $1 ) 1> >( greenchar $1 )
}
colorize ./script2.sh
#!/bin/bash
# script2.sh
echo "Hello GREEN"
>&2 echo "Hello RED"
>&1 echo "YES OR NO?"
select yn in "Yes" "No"; do
case $yn in
Yes) echo "YOU PICKED YES" ; break;;
No) echo "YOU PICKED NO" ; break;;
esac
done

示例输出,输出类似于这些命令的输出。

RED="33[0;31m"
GRN="33[0;32m"
NC="33[0;0m"
printf "./script1.sh:${GRN}Hello GREEN${NC}n"
printf "./script1.sh:${GRN}YES OR NO?${NC}n"
printf "./script1.sh:${RED}Hello RED${NC}n"
printf "./script1.sh:${RED}1) Yes${NC}n"
printf "./script1.sh:${RED}2) No${NC}n"
printf "${NC}1${NC}n"
printf "./script1.sh:${GRN}YOU PICKED YES${NC}n"

最新更新