dzen2是一种通知实用程序。此命令将在屏幕上显示“您好”的通知:
echo Hi | dzen2 -p
Run Code Online (Sandbox Code Playgroud)
Debian 的at是一个实用程序,用于安排将来发生的事件。此命令将使文件“foo”在 1 分钟后出现在您的用户目录中:
echo "touch ~/foo" | at now + 1 minute
Run Code Online (Sandbox Code Playgroud)
那么为什么这个命令不会dzen2在 1 分钟后导致出现通知呢?
echo "echo Hi | dzen2 -p" | at now + 1 minute
Run Code Online (Sandbox Code Playgroud)
我已经调查了几个小时,似乎找不到这不起作用的原因!我有一种预感,它与 at 调用的 shell 有关,但我只是不明白它为什么会失败。作为对位示例,此命令工作正常:
echo "notify-send Hi" | at now + 1 minute
Run Code Online (Sandbox Code Playgroud)
构成at作业的程序是atd(at daemon ) 进程的子进程,而不是您运行的 shell的子进程at。所以它不会继承当前shell的环境。该at系统整理复制的环境(和工作目录和一些比较模糊的东西),但它忽略了一些变数。
特别是,DISPLAY变量不会复制到 at 作业。此变量告诉所有 X 程序要连接到哪个显示器。没有 X 显示,dzen2 不知道在哪里弹出通知。DISPLAY因为它通常用于不产生任何终端或图形输出的批处理作业,所以删除。
notify-send工作是因为它没有连接到 X 服务器:它使用D-bus连接到附加到您的 X 会话的守护进程。
您可以通过显式复制DISPLAY变量来使 dzen2 工作:
echo "export DISPLAY=$DISPLAY;" 'echo hello | dzen2 -p' | at now + 42 minutes
Run Code Online (Sandbox Code Playgroud)
dzen2 很可能会产生错误消息(标准消息是Can't open display:)。at 作业产生的任何输出或错误消息都通过本地邮件发送(与 cron 作业完全一样)。检查您的本地邮件。