如何在 cron 作业中 运行 特定 shell 脚本?

How do I run a specific shell script in a cron job?

我已经设置了一个 cron 作业,它将 运行 一个 shell 脚本连接到我们的 Oracle 数据库并将一个 table 复制为 csv 文件。

crontab -l 输出:

*/5 * * * * /home/user/import.sh > /home/user/importLog.txt

import.sh 看起来像这样:

#!/bin/bash
FILE="/path/to/application/TABLE.csv"

sqlplus -s user/pw@db <<EOF

SET PAGESIZE 50000
SET COLSEP ","
SET LINESIZE 200
SET FEEDBACK OFF

SPOOL $FILE

SELECT * FROM TABLENAME;

SPOOL OFF
EXIT
EOF

现在,当我手动 运行 import.sh 时,它成功导入了 table 并创建了 csv 文件,而 cron 作业似乎 运行,因为它生成 importLog.txt(空白),但它不会创建 csv 文件。

Cron 作业 运行 具有非常 "impoverished" 的环境。您可能需要设置环境变量来定位您的 tnsnames 配置文件。您还期望 sqlplus 在命令路径上,如果您之前没有在 crontab 中设置它,则可能不会——我强烈建议将 sqlplus 二进制文件的完整路径放在脚本中.最后,添加

MAILTO=your@email.addr

尽早在您的 crontab 中确保您收到一封包含错误通知的电子邮件(假设您的 sendmail 配置设置正确)。

除了将 stderr 重定向到您的日志文件

import.sh > import.log 2>&1

注意:如果您想要 运行 日志(附加),则:

import.sh >> import.log 2>&1

您可能想要添加 每当 sqlerror 退出时 sql.sqlcode 在您的 shell 脚本中确保捕获错误:

sqlplus -s user/password << EOF
whenever sqlerror exit sql.sqlcode;

...
EOF

使用邮件和日志

如果您想将 stdout 和 stderr 都重定向到日志文件和邮件,您可以在大多数 *nix 系统上执行此操作:

* * * * * /path/to/import.sh 2>&1 | tee -a /path/to/import.log | mail -s "Output of import.sh" someuser@someaddr.com

这样你就有了 运行 日志文件和电子邮件警报(stderr 和 stdout)。如果需要,您还可以为 crontab 中的每个脚本设置不同的日志文件 and/or 电子邮件地址。