没有太多运气谷歌搜索这个问题,我想在SF上发布它,但它实际上似乎是一个开发问题。如果没有,请随意迁移。
所以,我有一个脚本每天凌晨3点左右通过cron运行。我有时也手动运行相同的脚本。问题是,每次我手动运行脚本并失败时,它都会向我发送一封电子邮件;即使我可以查看输出并在控制台中查看错误。
有没有办法让bash脚本告诉它是通过cron运行的(也许是通过使用whoami)并且只发送电子邮件,如果是这样的话?当我正在进行测试时,我很想停止接收电子邮件......
答案 0 :(得分:26)
您可以尝试“tty”查看它是否由终端运行。这不会告诉你它是由cron专门运行的,但你可以判断它是否“不是用户提示”。
你也可以得到你的父亲pid并在树上追查cron,虽然这有点笨拙。
答案 1 :(得分:9)
为什么没有命令行参数-t用于测试或-c用于cron。
或者更好:
-e=email@address.com
如果未指定,请勿发送电子邮件。
答案 2 :(得分:9)
以下是两种不同的选择:
通过电子邮件发送您的脚本/程序,让cron处理它。如果在crontab中设置MAILTO变量,cron将发送打印到该电子邮件地址的任何内容。例如:
MAILTO=youremail@example.com
# run five minutes after midnight, every day
5 0 * * * $HOME/bin/daily.job
在crontab中设置一个环境变量,用于确定是否在cron下运行。例如:
THIS_IS_CRON=1
# run five minutes after midnight, every day
5 0 * * * $HOME/bin/daily.job
并在您的脚本中
if [ -n "$THIS_IS_CRON" ]; then echo "I'm running in cron"; else echo "I'm not running in cron"; fi
答案 3 :(得分:7)
我有类似的问题。我通过检查stdout是否是TTY来解决它。这是检查脚本是否以交互模式运行的检查:
if [ -t 1 ] ; then
echo "interacive mode";
else
#send mail
fi
我从How to detect if my shell script is running through a pipe?
得到了这个如果文件描述符打开并且引用终端,则-t test返回true。 '1'是stdout。
答案 4 :(得分:6)
我知道这个问题很老,但我遇到了同样的问题。这是我的解决方案:
CRON=$(pstree -s $$ | grep -q cron && echo true || echo false)
然后用
进行测试if $CRON
then
echo "Being run by cron"
else
echo "Not being run by cron"
fi
与@eruciform提到的想法相同 - 跟随你的PID检查进程树检查cron。
注意:此解决方案仅适用于cron,与其他一些解决方案不同,后者可以在非交互式运行脚本时随时工作。
答案 5 :(得分:4)
对我有用的是检查$TERM
。在cron下,它是愚蠢的"但在一个外壳下它是别的东西。在终端中使用set
命令,然后在cron脚本中查看
if [ "dumb" == "$TERM" ]
then
echo "cron"
else
echo "term"
fi
答案 6 :(得分:4)
我想对这个高度投票的问题提出新答案。这仅适用于loginctl
的系统系统(例如Ubuntu 14.10 +,RHEL / CentOS 7+),但能够提供比以前提供的解决方案更具权威性的答案。
service=$(loginctl --property=Service show-session $(</proc/self/sessionid))
if [[ ${service#*=} == 'crond' ]]; then
echo "running in cron"
fi
总结:当与systemd一起使用时,crond
(如sshd
和其他人)在为用户启动作业时会创建新的session。此会话具有唯一的ID,用于整个机器的正常运行时间。每个会话都有一些属性,其中一个属性是启动它的服务的名称。 loginctl
可以告诉我们这个属性的价值,它将是&#34; crond
&#34; 当且仅当会话实际上是由crond启动的时候。
使用环境变量的优点:
测试tty的优点:
检查进程树的优点:
crond
的进程没有误报。答案 7 :(得分:0)
我也很喜欢Tal的想法,但也看到了未定义回报的风险。我最终得到了一个稍微修改过的版本,在我看来这似乎非常顺利:
CRON="$( pstree -s $$ | grep -c cron )"
因此,您可以随时检查$ CRON是1还是0。
答案 8 :(得分:0)
以前的文章中使用的许多命令并非在每个系统上都可用(pstree,loginctl,tty)。这是唯一对我已经使用了10年的BusyBox / OpenWrt路由器起作用的东西,我目前将其用作黑名单DNS服务器。它运行具有自动更新功能的脚本。从crontab运行,它将发送电子邮件。
[ -z "$TERM" ] || [ "$TERM" = "dumb" ] && echo 'Crontab' || echo 'Interactive'
在交互式外壳中,$TERM
变量为我返回值vt102
。因为@edoceo提到“哑巴”对他有用,所以我包括了“哑巴”支票。我没有使用'==',因为它不是完全可移植的。