【问题标题】:Shell script not running via crontab, but runs fine manuallyShell 脚本未通过 crontab 运行,但手动运行良好
【发布时间】:2014-01-02 03:35:50
【问题描述】:

我有一个脚本检查PPTP VPN 是否正在运行,如果没有,它会重新连接 PPTP VPN。当我手动运行脚本时,它执行得很好,但是当我做一个 cron 作业时,它没有运行。

* * * * * /bin/bash /var/scripts/vpn-check.sh

这是脚本:

#!/bin/sh
/bin/ping -c3 192.168.17.27 > /tmp/pingreport
result=`grep "0 received" /tmp/pingreport`
truncresult="`echo "$result" | sed 's/^\(.................................\).*$$'`"
if [[ $truncresult == "3 packets transmitted, 0 received" ]]; then
/usr/sbin/pppd call home
fi

【问题讨论】:

  • 这个sed 声明永远不会起作用。整个解决方案看起来很脆弱。为此使用if-up.d 脚本
  • 12 月 14 日 12:41:01 server3 CRON[5381]: (root) CMD (/bin/bash /var/scripts/vpn-check.sh )
  • @hek2mgl,为什么?无论如何,sed 应该有完整的路径,就像其他任何东西一样。
  • cron 作业无法运行的常见原因是权限和路径。请阅读cron man 条目几次,并尝试了解路径如何中断以及 cron 作业将在哪些权限下运行。
  • @user3101956 因为 sed 中的替换命令看起来像 s/PATTERN/REPLACEMENT/ 而你的只是 s/PATTERN

标签: bash shell


【解决方案1】:

如果您确定脚本在 cron 之外运行,请执行

printf "SHELL=$SHELL\nPATH=$PATH\n* * * * * /bin/bash /var/scripts/vpn-check.sh\n"

对您正在使用的 crontab 执行 crontab -e 并将其替换为上述命令的输出。这应该反映您的大部分环境,以防缺少路径问题或其他问题。还要检查日志是否有任何错误。

虽然看起来脚本有错误或者你在这里复制时搞砸了一些东西

sed: -e expression #1, char 44: unterminated `s' command
./bad.sh: 5: ./bad.sh: [[: not found

简单的替代脚本

#!/bin/bash

if [[ $(ping -c3 192.168.17.27) == *"0 received"* ]]; then
  /usr/sbin/pppd call home
fi

【讨论】:

  • 输出相同: * * * * * /bin/bash /var/scripts/vpn-check.sh
  • @user3101956 除非您错误地复制了某些内容,否则 sed 会损坏。
【解决方案2】:

您的脚本可以像这样更正和简化:

#!/bin/sh
log=/tmp/vpn-check.log
{ date; ping -c3 192.168.17.27; } > $log
if grep -q '0 received' $log; then
    /usr/sbin/pppd call home >>$log 2>&1
fi

通过我们在 cmets 中的讨论,我们确认脚本本身可以工作,但从 cron 运行时,pppd 不能。这是因为在交互式 shell(如终端窗口)和 cron 中必须有所不同。顺便说一下,这种问题很常见。

首先要做的是记住pppd需要什么配置。我没用过所以不知道。也许您需要设置一些环境变量?在这种情况下,很可能您在启动文件中设置了一些内容,例如 .bashrc,这通常不会在非交互式 shell 中使用,并且会解释为什么 pppd 不起作用。

第二件事是查看pppd的日志。如果您无法轻松找到日志,请查看其man 页面及其配置文件,并尝试查找日志或如何使其成为日志。根据日志,您应该能够找到在cron 中运行时缺少的内容,并解决您的问题。

【讨论】:

  • 脚本在没有 cron 的情况下工作 :) 我现在会尝试这个,我的意思是当我运行脚本时 ./vpn-check.sh 会检查并重新连接 vpn,当它在 cron 上时它不会' t重新连接它
  • 与此脚本相同,如果我执行 ./vpn-check.sh 它会检查 vpn 是否没有运行并重新连接它,当它在 cron 上时......它不会
  • tail -f /var/log/syslog | grep CRON 12 月 14 日 13:02:01 server3 CRON[5863]: (root) CMD (/bin/bash /var/scripts/vpn-check.sh)
  • 日志文件内容为:Sat Dec 14 13:12:01 EET 2013 PING 192.168.17.27 (192.168.17.27) 56(84) 字节数据。 --- 192.168.17.27 ping 统计 --- 传输 3 个数据包,收到 0 个数据包,100% 丢包,时间 2016ms
  • 12 月 14 日星期六 13:16:01 EET 2013 PING 192.168.17.27 (192.168.17.27) 56(84) 字节的数据。 --- 192.168.17.27 ping 统计 --- 传输 3 个数据包,收到 0 个数据包,100% 丢包,时间 2016ms
【解决方案3】:

作为其他答案的补充,您是否忘记了 crontab 脚本中的用户名?

试试这个:

* * * * * root /bin/bash /var/scripts/vpn-check.sh

编辑

这是你的代码补丁

#!/bin/sh
/bin/ping -c3 192.168.17.27  > /tmp/pingreport
result=`grep "0 received" /tmp/pingreport`
truncresult=`echo "$result" | /bin/sed 's/^\(.................................\).*$/\1/'`
if [[ $truncresult == "3 packets transmitted, 0 received" ]]; then
    /usr/sbin/pppd call home
fi

【讨论】:

  • 我修补了您代码的 sed 命令。这种方式对我有用。
【解决方案4】:

终于我找到了解决方案......而不是进入 cronjob

crontab -e

我需要直接编辑 crontab 文件

nano /etc/crontab

添加例如像

*/5 *     * * *   root  /bin/bash /var/scripts/vpn-check.sh

现在很好!

感谢大家的帮助......希望我的解决方案也能帮助其他人。

【讨论】:

  • 是的,这只是帮助了我。 crontab -e 是问题,在 RHEL 6.7 机器上:)
  • 这是一个不精确的答案。根本问题是crontab 语法有两种不同的变体。这个答案对于root 拥有的系统范围的crontab 是正确的,但您最初拥有的对于用户的私人crontab 来说是正确的。
  • 对我来说,只为 Ubuntu 16.04 添加 /bin/bash 有助于 crontab -e
【解决方案5】:

试试这个 /home/您的站点文件夹名称/public_html/gistfile1.sh 像上面一样设置 cron 路径

【讨论】:

    【解决方案6】:

    遇到了类似的问题,当 sh 放在 crontab 中的命令之前时已解决

    这不起作用:

    @reboot ~myhome/mycommand >/tmp/logfile 2>&1
    

    这样做了:

    @reboot sh ~myhome/mycommand >/tmp/logfile 2>&1
    

    【讨论】:

      【解决方案7】:

      在我的例子中,问题是脚本没有被标记为可执行。要确保它是,请运行以下命令:

      chmod +x your_script.sh

      【讨论】:

        【解决方案8】:

        经过很长时间的错误,我只是这样做了:

        SHELL=/bin/bash 
        PATH=/bin:/sbin:/usr/bin:/usr/sbin
        * * * * * /bin/bash /home/joaovitordeon/Documentos/test.sh
        

        其中test.sh 包含:

        #!/bin/bash 
        
        /usr/bin/python3  /home/joaovitordeon/Documentos/test.py; 
        

        【讨论】:

          【解决方案9】:

          问题陈述是脚本在 shell 中手动运行时正在执行,但是当通过 cron 运行时,它给出“java:command not found”错误 -

          请尝试以下 2 个选项,它应该可以解决问题 -

          1. 确保脚本是可执行的。如果不是,请在下面执行 - chmod a+x your_script_name.sh

          2. cron 作业不会与您手动执行脚本的同一用户一起运行 - 因此它无法访问与您的用户相同的 $PATH 变量,这意味着它无法将 Java 可执行文件定位到执行脚本中的命令。我们应该首先获取 PATH 变量的值,如下所示,然后在脚本中设置它(导出)-

          echo $PATH 可用于获取 PATH 变量的值。

          您的脚本可以修改如下 - 请参阅以 export 开头的第二行

          #!/bin/sh
          export PATH=<provide the value of echo $PATH>
          /bin/ping -c3 192.168.17.27 > /tmp/pingreport
          result=`grep "0 received" /tmp/pingreport`
          truncresult="`echo "$result" | sed 's/^\(.................................\).*$$'`"
          if [[ $truncresult == "3 packets transmitted, 0 received" ]]; then
          /usr/sbin/pppd call home
          fi
          

          【讨论】:

            【解决方案10】:

            首先,检查 cron 服务是否正在运行。您知道 IT 帮助台的第一个问题:“PC 插上电源了吗?”。

            【讨论】:

            • 这可能是为了搞笑,但我不明白这与答案有什么关系。
            • 谢谢,我忘记插电脑了 :)
            • 您的回复中没有任何内容与该问题相关。至少可以添加如何检查 cron 服务是否正在运行? crontab -l
            【解决方案11】:

            在我的情况下,可以通过以下方式解决:

            * * * * * root ( cd /directory/of/script/ && /directory/of/script/scriptItself.sh )
            

            我在脚本中使用了一些./folder/-references,但不起作用。

            【讨论】:

              猜你喜欢
              • 2011-01-14
              • 1970-01-01
              • 1970-01-01
              • 2016-12-18
              • 1970-01-01
              • 1970-01-01
              • 2019-11-24
              • 2020-09-10
              相关资源
              最近更新 更多