我写了一个脚本,向终端输出了很多消息.某些消息是提供信息的,其他消息是从
Shell命令输出的,有些是错误消息.为了使用户能够轻松读取终端中的输出,我想用红色对错误消息进行着色.
这工作正常,除了Carp :: confess生成的错误消息.例如:
use strict;
use warnings;
use Carp;
use Term::ANSIColor;
my_func(1);
sub my_func {
my ( $val ) = @_;
if( $val != 0 ) {
confess color("bold red")
. "Unexpected value. Abort." . color("reset");
}
}
输出看起来像这样(具有不同的行号):
问题是颜色过早重置,因此堆栈跟踪没有着色.如果省略颜色(“重置”)调用,堆栈跟踪也会着色,但是程序退出后终端提示符以及终端中运行的所有后续命令的输出都是红色.
这有可能实现吗?我已经尝试过两个$SIG {__ DIE__}处理程序和END块但它没有工作..
另见Coloring a perl die message.
最佳答案 看起来这可以使用模具信号处理程序完成(达到令人满意的水平).由于模信号处理程序将捕获远远超过调用承认(见
Override die with END or CORE::GLOBAL::die了解更多信息),我们将检查给定的领先ANSI转义序列模处理程序的输入参数.如果输入字符串包含颜色(“红色”),我们将假设我们被confess调用:
local $SIG{__DIE__} = sub {
my ( $msg) = @_;
my $col_red = color( "bold red" );
if ( $msg =~ /\Q$col_red\E/ ) {
$msg =~ s/\s+$//;
$msg .= (color("reset") . "\n");
}
die $msg;
};
然后,在我们编写的程序中
confess color("bold red") . "Unexpected value. Abort.";
因此省略了颜色(“重置”)代码.
编辑:
可以获得对上述的改进.由于脚本已经控制了每个confess调用,因此可以编写一个辅助子例程来更加本地化信号处理程序:
sub error_exit {
my ( $msg ) = @_;
local $SIG{__DIE__} = sub {
my ( $msg) = @_;
my $col_red = color( "bold red" );
if ( $msg =~ /\Q$col_red\E/ ) {
$msg =~ s/\s+$//;
die $msg . color("reset") . "\n";
}
else {
die $msg;
}
};
confess color("bold red") . $msg;
}
然后,在脚本中,使用error_exit调用替换每个confess调用.例如,对于问题中的脚本:
error_exit("Unexpected value. Abort.");