给 Perl 的 die 信息添加颜色

12
我想在Perl脚本中改变死亡消息的颜色。 我目前正在使用Term::ANSIColor来更改我的脚本中的其他颜色。 我遇到的问题是一旦脚本死亡,它就无法将颜色重置为终端默认值,终端提示符的颜色则为在我的脚本中上次使用的颜色。 在这种情况下,它将其变为红色。

您是否有任何想法,如何使脚本死亡但仍然改变颜色返回?

以下是相关的代码块;

#!/usr/bin/perl
use strict;
use warnings;
require Term::ANSIColor;
use Term::ANSIColor;

print "Loading configuration file\n";

# Check if the specified configuration file exists, if not die
if (! -e $config_file_path) {
    print color 'red';
    die "$config_file_path not found!\n";
    print color 'reset';
} else {
    print color 'green';
    print "$config_file_path loaded\n";
    print color 'reset';
}

更新

代码可以运行,但现在我无法去除 die 语句中显示出错行号的部分。

Loading configuration file
/etc/solignis/config.xml not found!
 at discovery.pl line 50.

通常我只需在die函数中添加一个换行符,就可以消除任何来自die的正常错误输出。 有什么想法为什么会这样?

更新2

根据你们所有人的建议,我将它拼凑在一起了。

print STDERR RED, "$config_file_path not found!";
die RESET, "\n";

看起来它运行正确。使用Term :: ANSIColor的常量1是我需要简化事情的完美选择。

4个回答

19

die会输出到 STDERR,而print则会输出到 STDOUT。

print STDERR color 'red';
die "$config_file_path not found!\n";

请注意,如果您使用 die 函数,则不会打印出重置操作。此时建议将其与 die 函数合并:

die color 'red' . "$config_file_path not found!" . color 'reset';

您也可以使用常量:

use Term::ANSIColor qw(:constants);

die RED, "THis is death!", RESET, "\n";

编辑:抱歉 - 要去掉"发生在哪里"的部分,可以在末尾加上一个\n

die color 'red' . "$config_file_path not found!" . color 'reset' . "\n";

明白了 - 抱歉,我忘记了\n的作用。color函数所做的只是返回一个控制字符,终端会将其解释为颜色更改,因此您正在使用连接将该字符包含在字符串中。 - Brian Roach
+1 给你,使用 Term::ANSIColor qw(:constants); 的想法真是太棒了。谢谢。 - AtomicPorkchop
更正,你更新后的解决方案非常完美。我喜欢它能在一行上适应的方式。 - AtomicPorkchop
请注意,您也可以对常量执行相同的操作 - 只需将\n附加在末尾即可(我刚刚更新了这一点)。 - Brian Roach
是的,我已经想到了,我从来没有使用过字符串连接。因此,我可以通过很大程度上减少代码量。 - AtomicPorkchop

7
有几种方法可以实现这个目标。
第一种是使用Term::ANSIColor的colored函数,该函数似乎会自动在末尾添加ANSI重置序列。
die colored( "$config_file_path not found!\n", 'red' );

使用来自 Term::ANSIColor 的常量接口:
use Term::ANSIColor qw( :constants );
$Term::ANSIColor::AUTORESET = 1;
die RED "$config_file_path not found!\n";

或者

die RED, "$config_file_path not found!\n", RESET;

您也可以使用END块和代码引用来捕获$SIG{__DIE__},并在打印其参数后重置它。 (这可能不是最好的想法,但它们允许您在几乎任何退出情况下重置颜色。)


END{ }块是最好的方式。**++** - Alan Haggai Alavi

4

我相信,在 END{} 块中将终端重置为黑色是最干净的解决方案。这就是这些东西的用途。

不要轻易更改 $SIG{__DIE__},否则你会很不开心。没有人意识到它甚至会被捕获的异常调用!!


是的,我尝试过$SIG{__DIE__},尽管我不知道它的作用。无论如何,它对我没有起作用。 - AtomicPorkchop
END{ }块是最好的方式。**++** - Alan Haggai Alavi

0

你可以使用 __DIE__ 处理程序:

$SIG{'__DIE__'} = sub {
    print color 'reset';
};

来自perldoc perlvar:

由于实现上的问题,即使在eval()内部,也会调用$SIG{__DIE__}钩子。

因此,您可能不应该使用这种技术。


每个被捕获的异常都应该打印那个简陋的东西吗?唉! - tchrist
tchrist: 添加了一条关于它的引用。谢谢。 - Alan Haggai Alavi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接