【问题标题】:Bash script works standalone, won't work in crontabBash 脚本独立工作,不能在 crontab 中工作
【发布时间】:2015-07-14 12:07:15
【问题描述】:

我设置了一个 bash 脚本来从远程驱动器复制备份;如果我从终端运行它,这个脚本就可以正常工作,即$ ./getBackup;但是,如果我尝试将它放在我的 crontab 中,它就不起作用。

我在这里阅读了一堆问题/答案,包括

也许我错过了一些东西,但我想我已经尝试了其中提供的大部分建议,以及我能想到的所有其他建议。我试图从我的 crontab、sudo crontab、/etc/crontab 运行它;我检查了终端的环境(脚本手动工作的地方)并将其放入 cron 作业的脚本中。

有人有什么想法吗?

[编辑添加] 一些评论者询问了有问题的代码,所以:

crontab:

30 9 * * * /home/opsmonitor/Documents/getBackup

获取备份

cd /home/opsmonitor/Documents/
OF=backup-$(date +%Y%m%d)
echo "Retrieving backup file $OF"
scp root@IP ADDRESS HERE://opt/backups/backupsbydate/$OF.tgz $OF.tgz

正如我所说,getBackup 在命令行中运行良好;并从 crontab 运行,它什么也不做。 (现在我将输出重定向到一个文件,回显确实打印到该文件。)

由于 scp 从命令行运行,我认为这是一个 env 问题,但正如我所说,我在脚本中添加了很多 env 变量——它仍然从命令行运行良好,但从crontab。

【问题讨论】:

  • 将您的 cron 条目添加到问题中。
  • getBackup 脚本的内容也可能有用。您是否在脚本中添加了显式错误日志(到文件)以尝试查看 cron 运行时发生了什么?
  • 即使 OP 正确设置了环境变量,脚本也有可能尝试使用 /dev/tty ...
  • Cron 通常运行作业 a) 使用有限的 PATH,b) 不是作为登录 shell,c) 不使用 ~/.bashrc 或 ~/.cshrc,并且 d) 使用 $ 的 PWD家。因此,a)确保您的 PATH 设置正确,b)使用完整路径(不是“./getBackup”,以及 c)所有其他必需的环境变量都是正确的。
  • 由于您没有向我们展示脚本,因此很难诊断出哪里出了问题。您是否在 crontab 条目中使用bash -x /path/to/getBackup >/tmp/getBackup 2>&1 运行脚本,以便获得bash 认为正在发生的事情的记录? cron运行作业时,你记录了实际环境(当前目录和环境变量是关键)?如果没有,你应该这样做。其中一个很有可能解释了这个问题。

标签: linux bash shell cron


【解决方案1】:

我通过在删除额外环境变量的脚本中运行我的程序来测试环境方面。这是一个示例(请注意,它实际上只留下了 PATH — 并不是您想要的):

#!/bin/sh
# $Id: noenv,v 1.3 2014/05/10 22:43:32 tom Exp $
# trim the environment to minimal (PATH may still be long...)
env | sed -e 's/=.*//' -e '/^[  ].*/d' | \
while true
do
    read value
    if test -z "$value" ; then
            # honor assignments to variables in the parameter list
            while test $# != 0
            do
                    case "x$1" in
                    *=*)
                            eval $1
                            name=`echo "$1"|sed -e 's/=.*//'`
                            export $name
                            shift 1
                            ;;
                    *)
                            break
                            ;;
                    esac
            done
            exec "$@"
            break
    fi
    case "$value" in
    HOME|PATH|USER|_|SHLVL|TMPDIR|LOGNAME)
            ;;
    *\ *|*\(*|*\)*|*\!*)
            #echo "...skipping $value"
            ;;
    *)
            #echo value:"$value"
            unset "$value"
            ;;
    esac
done

然后调用noenv,就可以了

noenv ./getBackup

但是,如果您的程序 仍然 从命令行正常工作,我怀疑它会尝试使用 /dev/tty 等,如果没有找到终端则失败。这是 cron 中不太常见的问题,但例如在 Linux: Difference between /dev/console , /dev/tty and /dev/tty0 中注明。

【讨论】:

    猜你喜欢
    • 2015-10-25
    • 2017-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多