Hack and / - 给您的消息先生
守护进程很容易被遗忘,除非它们需要您的注意。几年前,我在 OSCON 的展厅里走动,当我注意到有人穿着全套 BSD 守护进程服装,和一些粉丝合影留念。当我看到他们试图弄清楚如何安排所有人拍照时,我不禁喊道:“不!守护进程总是在后台!”
如果您没有理解这个笑话,守护进程(dæmon) 是 UNIX 人们给在幕后(在后台)运行的进程的名称。守护进程执行各种有用的功能,从在特定时间执行脚本(atd 和 crond)到监听网络连接并生成适当的进程来服务请求(inetd)。实际上,这些脚本末尾的 d 代表守护进程,您可能会注意到,您系统上现在有许多进程以 d 结尾。
守护进程的重点是在没有您的干预或知识的情况下执行任务,但有时,当特定条件发生时,守护进程向您发出警报会很方便。在服务器上,这通常意味着守护进程会向管理员发送电子邮件警报,但是在桌面上呢?如果您希望守护进程在您有新电子邮件时提醒您怎么办?在这种情况下,在桌面上弹出某种通知更有意义。在本专栏中,我将讨论我使用的三种不同方法,以便守护进程可以在我的桌面上引起我的注意。
我想我第一次注意到 Linux 上的 OSD(屏幕显示)通知是在使用音量控制程序时。我增加了电脑的音量,屏幕正中央出现了一个音量计,像电视一样浮在我所有其他窗口之上。我立刻被它吸引住了,必须弄清楚他们是怎么做到的。如今,有许多不同的 OSD 库和程序,但我最喜欢的仍然是 osd_cat。
osd_cat 程序是一个命令行程序,它显示通过管道发送给它的文本。它接受管道输入这一事实使其非常适合守护进程通知,因为它很容易添加到任何 shell 脚本中。此命令是基于 Debian 的系统上的 xosd-bin 软件包或 Red Hat 上的 xosd 的一部分,并且已经存在多年。
测试 osd_cat 最简单的方法是将一些文本通过管道传递给它
$ echo "Hello World" | osd_cat
如果您查看屏幕的左上方,您应该看到您的消息以红色小字体出现几秒钟,然后消失。当然,如果您不知道要看那里,您可能会认为程序坏了,因为消息太小了。另外,每个人都知道绿色是理想的前景色,因此让我们稍微修饰一下该通知,并将其放在屏幕的中心位置
$ echo "Hello World" | osd_cat --align=center --pos=bottom ↪--color=green --font=lucidasanstypewriter-bold-24
啊哈,这样更像样了,通知就在屏幕的正中央。如您所见,osd_cat 接受许多选项,可以控制消息的显示方式和位置。手册页详细介绍了所有选项,但我在这里重点介绍我使用的选项。 --align 参数控制文本对齐方式,很像文字处理器,可以设置为 left(默认)、center 或 right。 --pos 选项控制屏幕上的 Y 轴方向,可以设置为 top(默认)、middle 或 bottom。 --color 选项是不言自明的,--font 也是如此。如果您确实想要不同的字体,但不确定要使用什么值,只需运行xlsfonts即可查看完整列表。
除了我列出的选项外,osd_cat 还有许多其他选项,例如 --indent 和 --offset,它们允许您微调文本的显示位置,因此您可以将其放置在屏幕上的几乎任何位置。您还可以使用 --delay 选项调整消息在屏幕上显示的时间,如果您计划将多行文本通过管道传递到屏幕,请务必查看 --lines、--age 和 --wait 选项,以便您可以控制 osd_cat 如何滚动多行。甚至还有 --barmode 和 --percentage 选项,可让您绘制滑块栏,很像我看到的 OSD 音量控制。
所有这些选项都不错,但老实说,我发现自己坚持使用带有 osd_cat 的基本文本通知,尽管我已经将许多脚本迁移到 libnotify,但我仍然喜欢将 osd_cat 用于音频/视频通知,例如当我使用我编写的脚本打开笔记本电脑上的 VGA 输出以进行演示时。我在最初的 Lightning Hacks 专栏中提到了这个脚本,但如果您没有看到它,这里再次提供
#!/bin/sh if xrandr | grep -q 'VGA connected'; then echo "LVDS + VGA" | osd_cat --shadow=2 --align=center ↪--pos=bottom --color=green --delay=2 ↪--font=lucidasanstypewriter-bold-24 --offset 40 & # choose my laptop screen's resolution by default; # if that fails, try the auto-detected mode xrandr --output VGA --mode 1280x768@60 || xrandr ↪--output VGA --auto else echo "LVDS only" | osd_cat --shadow=2 --align=center ↪--pos=bottom --color=green --delay=2 ↪--font=lucidasanstypewriter-bold-24 --offset 40 & xrandr --output VGA --off & fi
我发现,每当我在后台通过按键绑定触发脚本时,添加这样的视觉通知会很好,而且脚本的运行并不总是立即显而易见的,例如在这种情况下,我想知道我是在演示模式还是常规模式,并且投影仪可能需要几秒钟才能响应。
我曾经在系统上的所有类型的脚本中使用 OSD 通知,包括一个在我收到新电子邮件时通知我的脚本。它工作正常,但有时我宁愿收到一个更容易忽略的通知。虽然我想我可以将我的 OSD 警报移到屏幕的角落,但那样就太容易错过了。我想要一些可以引起我的注意但又不会妨碍我正在做的事情的东西。目前,我使用 GNOME 作为我的桌面环境,我意识到它的桌面通知非常理想。它们抓住了我的眼角,但它们不会跳到我正在做的所有其他事情的前面。
GNOME 用于通知的库是名为 libnotify 的库,事实证明,使用 notify-send 命令将我的通知从 osd_cat 迁移到 libnotify 非常简单。因为我已经在使用 GNOME,所以该程序已经安装了。如果您的系统上没有安装,请查找名为 libnotify-bin 的软件包或在您的软件包管理器中搜索 notify-send。
notify-send 的语法比 osd_cat 简单得多,因为消息的位置和字体已经为您处理好了。这是一个简单的例子
$ notify-send "Message for you Sir" "Hello World"
这将在我的桌面上弹出一个通知窗口中的基本消息。第一组引号指定消息的标题,下一组引号定义消息的正文。
当然,当我使用 notify-send 提醒我收到新电子邮件时,我会使用更复杂的东西。如果您想为自己设置电子邮件通知,这是一个更简化的个人脚本版本,可帮助您入门。首先,设置 fetchmail,以便它可以连接到您的 IMAP 服务器。只是警告一下,除非您确实想将所有邮件下载到本地计算机,否则永远不要在没有 -c 选项的情况下运行 fetchmail。配置 fetchmail 后,您可以使用以下命令测试它是否有效fetchmail -c:
$ fetchmail -c 991 messages (990 seen) for kyle at mail.example.net (folder INBOX). 530 messages (530 seen) for kyle at mail.example.net (folder INBOX.nblug). 284 messages (284 seen) for kyle at mail.example.net (folder INBOX.linuxjournal).
如您所见,我在 INBOX 文件夹中收到了一条新消息,我还没有看到。您现在需要做的就是编写一个脚本来执行fetchmail -c,解析输出,并统计总邮件数和已读邮件数。如果总数不同,则您有新邮件,并且可以执行 notify-send 并显示相应的消息。这是一个更进一步的快速 Perl 脚本,它可以跟踪每个包含新消息的文件夹,以便它可以列出它们及其计数
#!/usr/bin/perl open FETCHMAIL, "/usr/bin/fetchmail -t 10 -c 2>/dev/null ↪|" or die "Can't run fetchmail: $!\n"; while(<FETCHMAIL>){ if(/^(\d+) messages \((\d+) seen.*?folder (.*?)\)/){ # keep a running total of all messages and seen messages $messages+=$1; $seen+=$2; $folder=$3; $folder =~ s/INBOX\.//; # strip the INBOX. # from the folder names } # If there are more messages than seen messages, # store the difference if($1 > $2){ $folders{$folder} = $1 - $2; } } close FETCHMAIL; $total = $messages - $seen; if($total > 0){ foreach $folder (sort { $folders{$a}<=>$folders{$b} ↪} keys %folders){ push @list, "$folder:$folders{$folder}"; } $output = join " ", @list; system ("notify-send -u low -i /usr/share/pixmaps/mutt.xpm ↪-t 5000 'New Mail' '$output'"); }
请注意,在这个例子中,我在 notify-send 中添加了一些额外的选项。首先,我使用了 -u 选项,以便可以将消息的紧急程度设置为 low、normal 或 critical。 -i 选项允许我指定要添加到图像的图标,所以我选择了我的系统的 mutt 图标,因为那是我将用来阅读邮件的程序。接下来,我使用了 -t 选项,以便可以以毫秒为单位设置消息的超时时间。最后,我添加了消息的标题和正文。
如果您自己设置了此功能,那么您现在需要做的就是保存脚本并将其添加到用户的 crontab 中,以便它以您希望的频率运行以检查新邮件。我还建议向脚本添加某种形式的节流,以便它仅在少数几次通知您当前批次的新邮件。这样,如果您无法立即处理您的电子邮件,通知也不会变得烦人。
桌面通知很棒,但是如果通知出现时我没有看着屏幕怎么办?当然,如果脚本每分钟运行一次,我最终会看到它,但我为这些类型的通知设置了节流。我想出了一种比 libnotify 侵入性更小的通知,即使我的屏幕空闲并变为空白,它也会提醒我收到新邮件:我的键盘 LED。
现在,使用键盘 LED 进行通知当然不是什么新鲜事——毕竟,它们的预期用途是通知您有关大写锁定、数字锁定和滚动锁定键的状态。但是,如今您多久使用滚动锁定,甚至大写锁定?我的意思是,我的许多朋友甚至对我这个 UNIX 极客也彻底失望了,并将大写锁定重新映射回 Ctrl 键。您的键盘 LED 是三个等待使用的通知区域,而 Linux 有大量实用程序可以使用它们。
我尝试了一些不同的工具,这些工具允许我从脚本控制键盘 LED,但我最终选择了 blinkd 作为我的最爱。当系统启动时,此程序作为守护进程运行(看到末尾的 d 了吗?),我喜欢它的原因是它不仅允许您控制所有三个键盘 LED,而且还可以设置 LED 闪烁的次数——非常适合跟踪新电子邮件消息。
要安装 blinkd,请使用您的软件包管理器查找同名的软件包。安装完成后,如果您的软件包管理器没有自动启动它,请运行/etc/init.d/blinkd start。守护进程运行后,您可以通过 blink 命令控制 LED。语法非常简单。例如,如果我想让滚动锁定键闪烁一次,我会输入
$ blink -s -r 1
-s 参数告诉它激活滚动锁定 LED,-r 告诉它在暂停之前闪烁多少次。我也可以使用 -c 或 -n 而不是 -s 来分别闪烁大写锁定或数字锁定 LED。您也可以将闪烁次数设置为 0 以关闭特定 LED 的闪烁,或键入blink -r 0以关闭所有 LED 的闪烁。
因为我上面编写的脚本已经有了新消息的总数,所以让我的滚动锁定键闪烁该次数非常简单。这是我的脚本的修改部分
if($total > 0){ foreach $folder (sort { $folders{$a}<=>$folders{$b} ↪} keys %folders){ push @list, "$folder:$folders{$folder}"; } $output = join " ", @list; system ("notify-send -u low -i /usr/share/pixmaps/mutt.xpm ↪-t 5000 'New Mail' '$output'"); system ("blink -s -r $total"); } else { system ("blink -r 0"); }
使用键盘 LED 进行通知的好处是,您最终会从眼角注意到它,特别是如果您离开计算机一分钟,但如果您正在工作,它不会完全分散您的注意力。我也喜欢我可以一目了然地知道我有多少新消息。如果您想进一步扩展脚本,我建议将您的文件夹分为常规和高优先级,并使脚本根据哪些文件夹有新邮件而闪烁不同的 LED。如果您有多个电子邮件帐户,您甚至可能想要多个版本的脚本,每个帐户分配一个 LED。我想说可能性是无限的,但事实并非如此。您只有三个 LED 可以玩。
在本专栏中,我主要提到检查电子邮件作为桌面通知的候选对象,但是您可能希望获得通知的还有许多其他内容,例如系统温度、由本地邮件或打印机队列触发的 LED、由 RSS 源(或者我敢说,Twitter)更新触发的通知,甚至是由您的服务器监控系统触发的桌面通知。当有需要报告的内容时,为什么还要让所有这些守护进程在后台静默运行呢?
Kyle Rankin 是旧金山湾区的系统架构师,也是许多本书的作者,包括 The Official Ubuntu Server Book(《Ubuntu 服务器官方指南》)、Knoppix Hacks(《Knoppix 秘籍》)和 Ubuntu Hacks(《Ubuntu 秘籍》)。他目前是北湾 Linux 用户组的主席。