![如何覆盖 at 命令使用的电子邮件地址](https://linux22.com/image/70413/%E5%A6%82%E4%BD%95%E8%A6%86%E7%9B%96%20at%20%E5%91%BD%E4%BB%A4%E4%BD%BF%E7%94%A8%E7%9A%84%E7%94%B5%E5%AD%90%E9%82%AE%E4%BB%B6%E5%9C%B0%E5%9D%80.png)
cron
具有MAILTO
明确配置将接收报告的电子邮件地址的设置
at
有类似的东西吗?
手册页显示它将使用发送/usr/sbin/sendmail
但将使用哪个目标地址?
我在那台机器上只安装了 exim,发送到 @ 的电子邮件丢失了(.forward
收件箱中也看不到任何信件)。
答案1
at
假设您在 glibc (Linux) 系统上使用 Thomas Koenig 的(现在由何塞·卡拉里斯维护),这是可能的,但没有明确记录,来自at(1)
:
如果文件 /var/run/utmp 不可用或已损坏,或者用户在调用 at 时未登录,则邮件将发送到环境变量 LOGNAME 中找到的用户 ID。如果未定义或为空,则假定当前用户 ID。
工作方式at
是构建一个作业文件atd
,其前三行如下:
#!/bin/sh
# atrun uid=100 gid=100
# mail youruser 1
其中uid=100
、gid=100
和youruser
是在创建作业时以编程方式确定的。判断用户名的逻辑是:
- 称呼
getlogin()
- 如果这是 NULL 调用
getenv("LOGNAME")
- 通过调用检查名称是否存在
getpwnam()
- 如果这是 NULL 调用
getpwuid(real_uid)
- 如果为 NULL,则将所有玩具从婴儿车中扔出
那么,我们如何才能说服getlogin()
返回 NULL 以便使用 LOGNAME 变量呢?一种方法是安排 stdin不是是一个终端(这就是为什么我认为 glibcgetlogin()
在不同系统中的行为不同)。
要执行此操作,请执行以下操作bash
:
LOGNAME=backup at 19:52 -m <<< uptime
echo uptime | LOGNAME=backup at 19:52 -m
重点是使用重定向在标准输入上显示要运行的命令at
。 (at
还执行重新开放如果您使用它的选项,则可以使用 stdin 的-f
选项,尽管在这里使用已经太晚了。)您可以将命令保存到文件中,或者使用 bash 来保存创建文件:
LOGNAME=backup at 19:52 -m -f <( echo uptime ) 0<&-
(0<&-
关闭标准输入,< /dev/null
也可以)
如果您的终端(或screen
或tmux
)忽略utmp
(通过配置,或者通过权限或帮助程序问题),您甚至可以直接设置LOGNAME
并正常使用,at
因为getlogin()
会失败。您可以通过使用找到您的终端tty
然后检查w
您是否正确登录到该 tty 来判断是否是这种情况,或者尝试perl -E 'say getlogin()||"not-in-utmp";'
。
(需要明确的是,LOGNAME只能是本地用户名,如果您需要电子邮件到其他地方,则需要使用aliases
/ .forward
/procmail
等。)