Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash脚本是否可以判断';什么是通过cron运行的?_Bash_Cron - Fatal编程技术网

bash脚本是否可以判断';什么是通过cron运行的?

bash脚本是否可以判断';什么是通过cron运行的?,bash,cron,Bash,Cron,在谷歌上搜索这个问题运气不好,我想把它发布在旧金山,但实际上这似乎是一个发展问题。如果没有,请随时迁移 所以,我有一个脚本,每天早上3点左右通过cron运行。我有时也手动运行相同的脚本。问题是每次我手动运行脚本失败时,它都会向我发送一封电子邮件;即使我可以查看输出并在控制台中查看错误 bash脚本是否有办法告诉您它正在通过cron运行(可能是通过使用whoami),并且只有在这样的情况下才发送电子邮件?当我进行测试时,我想停止接收电子邮件…您可以尝试“tty”查看它是否由终端运行。这不会告诉您它

在谷歌上搜索这个问题运气不好,我想把它发布在旧金山,但实际上这似乎是一个发展问题。如果没有,请随时迁移

所以,我有一个脚本,每天早上3点左右通过cron运行。我有时也手动运行相同的脚本。问题是每次我手动运行脚本失败时,它都会向我发送一封电子邮件;即使我可以查看输出并在控制台中查看错误

bash脚本是否有办法告诉您它正在通过cron运行(可能是通过使用whoami),并且只有在这样的情况下才发送电子邮件?当我进行测试时,我想停止接收电子邮件…

您可以尝试“tty”查看它是否由终端运行。这不会告诉您它是由cron专门运行的,但是您可以告诉您它是否“不是作为提示的用户”


您还可以获取父pid,并在树上查找cron,尽管这有点麻烦。

为什么不使用命令行参数-t进行测试,或者-c进行cron测试

或者更好:

-e=email@address.com


如果未指定,请不要发送电子邮件。

这里有两个不同的选项供您选择:

  • 将电子邮件从脚本/程序中取出,让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
    

    • 我知道这个问题很老,但我刚刚遇到了同样的问题。这就是我的解决方案:

      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提到的想法相同——在进程树检查cron的过程中跟踪PID


      注意:此解决方案仅适用于cron,与其他一些解决方案不同,这些解决方案可以在脚本以非交互方式运行时随时工作。

      对我有效的方法是选中
      $TERM
      。在cron下它是“哑的”,但在shell下它是其他的东西。在终端中使用
      set
      命令,然后在cron脚本中检查它

      if [ "dumb" == "$TERM" ]
      then
          echo "cron"
      else
          echo "term"
      fi
      

      我也有类似的问题。我通过检查stdout是否是TTY解决了这个问题。这是一项检查,以查看脚本是否以交互模式运行:

      if [ -t 1 ] ; then 
          echo "interacive mode";
      else
          #send mail
      fi
      
      我是从以下方面得到的:


      如果文件描述符打开并且引用了一个终端,-t测试将返回true“1”是标准答案。

      我想为这个投票率很高的问题提出一个新的答案。这只适用于带有(例如Ubuntu 14.10+、RHEL/CentOS 7+)的systemd系统,但能够给出比以前提供的解决方案更权威的答案

      service=$(loginctl --property=Service show-session $(</proc/self/sessionid))
      if [[ ${service#*=} == 'crond' ]]; then
         echo "running in cron"
      fi
      

      service=$(loginctl--property=service show session$)(我也喜欢好未来的想法,但也看到了未定义回报的风险。我最终得到了一个稍加修改的版本,在我看来它运行得非常顺利:

      CRON=“$(pstree-s$| grep-c CRON)”


      因此,您可以随时检查$CRON是否为1或0。

      以前文章中使用的许多命令在每个系统上都不可用(pstree、loginctl、tty)。这是我目前用作黑名单DNS服务器的一个10年历史的BusyBox/OpenWrt路由器上唯一对我有效的东西。它运行一个带有自动更新功能的脚本。从crontab运行,它会发送一封电子邮件

      [ -z "$TERM" ] || [ "$TERM" = "dumb" ] && echo 'Crontab' || echo 'Interactive'
      

      在一个交互式shell中,
      $TERM
      -变量为我返回值
      vt102
      。我包括了“dumb”的检查因为@edoceo提到它对他有效。我没有使用“==”,因为它不是完全可移植的。

      你是从你的脚本中发送电子邮件吗?默认情况下,cron不是将邮件输出发送给crontab的所有者吗?我是从内部发送电子邮件,但我需要发送输出。我不知道cron会这样做。他们会像“mai”中那样使用实际发送的电子邮件吗l',不仅仅是使用unix邮件系统。我将脚本放在/etc/cron.daily中,因此我无法轻松添加参数,但我想我可以将它移动到一个真正的crontab中。我只是希望不必在命令行上添加参数或设置环境变量……不过:在.bashrc文件中设置测试环境变量就可以了。感谢您的建议。将myscript.sh arg1 arg2 arg3放入/etc/cron.daily中的脚本文件没有问题。我通常不会将我的脚本/二进制文件直接放入/etc/cron.*dirs中。我通常将其留给执行cron作业的脚本(可能是另一个脚本)。然后我可以编写更通用的脚本并在其他环境中使用。感谢您的回答!我选择的前一个答案实际上不是我想要的(交互式shell)。由于您的回答,我通过谷歌搜索“bash tty test”找到了我真正需要的。基本上,在脚本中调用
      tty-s
      ,然后选中
      $?
      :如果它是0,则您在tty中,如果它大于0,则不在tty中。
      tty
      是一个外部命令(被授予coreutils的一部分,但仍然是一个fork),有几种方法可以使用内置的东西来实现在中描述的相同功能,我喜欢将var设置为true或false(命令)的简单性,这样如果$CRON起作用(与通常的if[“$CRON”]”相反),但请注意,如果$CRON由于某种原因最终未定义,则给定的版本将评估为true。不太好。我也喜欢这个想法,但也看到了未定义回报的风险。我最终得到了一个稍微修改的版本,在我看来它运行得非常顺利:CRON=“$(pstree-s$| grep-c CRON)”因此,您可以检查$CRON是1还是0。我还将检查$TERM是否为空。
      [-n“$TERM”-a“$TERM”==“dumb”]&&echo“interactive”| echo“CRON”或no tty”
      遗憾的是,与其他systemd命令一样,它非常冗长且不明显。