是什么阻止我将“600”文件传输到 launchd 中的邮件中?

是什么阻止我将“600”文件传输到 launchd 中的邮件中?

在 OSX 10.6 中,我使用这个 plist 通过 launchd 运行 logcheck.sh

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>org.logcheck</string>
<key>Program</key><string>/opt/local/bin/logcheck.sh</string>
<key>StartInterval</key><integer>600</integer>
</dict>
</plist>

logcheck 按照指定的间隔运行,但它不会使用以下命令向我发送邮件:

cat $TMPDIR/checkreport.$$ | $MAIL -s "$HOSTNAME $DATE system check" $SYSADMIN

在哪里

$TMPDIR=/opt/local/var/tmp
$MAIL=/usr/bin/mail
$SYSADMIN=myuser

但是,如果我破解它,并将命令更改为:

cat $TMPDIR/checkreport.$$ > /Users/myuser/report
cat /Users/myuser/report | $MAIL -s "$HOSTNAME $DATE system check" $SYSADMIN

然后我收到了邮件。

$ls -l /opt/local/var使用 I get检查 tmp 上的权限

drwx------  20 root  admin  680 Jul 12 13:29 tmp/

如果我运行sudo /opt/local/bin/logcheck.sh第一个命令,它就有效。

如果我/opt/local/bin/logcheck.sh在 root 的 crontab 中使用,第一个命令就会有效。

如果我输入脚本,echo "$(whoami)" > /Users/myuser/launchduser我发现它确实是由 root 运行的。

为什么我使用 launchd 中的第一个命令时没有收到邮件?这是邮件管道的权限问题吗?

答案1

我最近一直在自己研究这个问题,并在系统日志(/var/log/system.log)中发现了与此问题相关的错误,例如:

Nov  1 08:52:14 my-computer com.apple.launchd[1] (org.postfix.master[22591]): Stray process with PGID equal to this dead job: PID 22592 PPID 1 pickup
Nov  1 08:52:14 my-computer com.apple.launchd[1] (org.postfix.master[22591]): Stray process with PGID equal to this dead job: PID 22594 PPID 1 cleanup

我发现我的 logcheck 脚本和预期的电子邮件从命令行执行时工作完美,并且当通过 LaunchDaemon 脚本使用 launchd 启动时,logcheck 脚本能够很好地执行其功能。

但是,使用 时邮件从未到达launchd。上述错误以及许多其他涉及 postfix 和 sendmail 的错误表明,子 sendmail 进程在完成之前就被 launchd 终止了(作为其垃圾收集例程的一部分?)。

我在 plist 中添加了以下键:

<key>AbandonProcessGroup</key>
</true>

并且使用 launchd 时邮件开始流动。不幸的是,我的 system.log 中仍然会收到杂散进程/死作业消息,我目前正在努力消除这些消息。我sleep 120logcheck.sh脚本中添加了一行,这减少了这些消息,但并没有消除它们。我可以延长 sleep 命令的时间logcheck.sh,以便脚本可以持续更长时间,但我不喜欢这种特定的“黑客”,我想找到一个更优雅的解决方案。我相信 launchd 直到 logcheck.sh 进程完成后才开始垃圾收集……

我将尝试明确延长控制 plist 中的 TimeOut 键,看看是否效果更好。

答案2

出于好奇,当您的脚本成功发送报告时,主体是空的吗?

我之所以问这个问题,是因为如果 /Users/myuser/report 可写,即使您无法读取 $TMPDIR/checkreport.$$,您的解决方法也始终会生成一封电子邮件。正文将为空,但您会收到带有相应主题行的电子邮件。

当你运行类似这样的程序时会发生什么?

if [ -r $TMPDIR/checkreport.$$ ]; then
    <$TMPDIR/checkreport.$$ $MAIL -s "$HOSTNAME $DATE system check" $SYSADMIN
else
    echo "Unable to read file: $TMPDIR/checkreport.$$" | $MAIL -s "ERROR: $HOSTNAME $DATE system check" $SYSADMIN
fi

如果 $TMPDIR/checkreport.$$ 存在且可读,这才会尝试发送报告电子邮件,否则您应该收到一封电子邮件,告诉您无法读取的明确文件名,然后您可以从那里进行调查。

顺便提一下,我刚刚删除了 cat 命令,因为它会启动一个不必要的进程。最终结果是一样的,但将文件内容直接重定向到邮件命令,而不是将 cat 的输出通过管道传输给它,这样更简洁一些。

答案3

您的ls输出清楚地表明你的用户无法输入也无法读取$TMPDIR,因此即使他可以读取该文件,他也无法读取它。

正如已经指出的那样,即使无法进入临时目录,您的第二个黑客也会简单地创建一个空文件......因此邮件到达,但是是空的。

你应该

  • 将您的用户添加到管理员组
  • 使$TMPDIR 加权

以便用户可以使用该文件。

相关内容