![Bash 脚本手动运行,但在 crontab 上失败](https://linux22.com/image/605220/Bash%20%E8%84%9A%E6%9C%AC%E6%89%8B%E5%8A%A8%E8%BF%90%E8%A1%8C%EF%BC%8C%E4%BD%86%E5%9C%A8%20crontab%20%E4%B8%8A%E5%A4%B1%E8%B4%A5.png)
我是 shell 脚本的新手。我编写了一个 shell 脚本来对 MySQL 数据库进行增量备份。该脚本是可执行格式,手动执行时可以成功运行,但通过 crontab 执行时会失败。
Crontab 条目如下: */1 * * * * /home/db-backup/mysqlbackup.sh
以下是 shell 脚本代码 -
#!/bin/sh
MyUSER="root" # USERNAME
MyPASS="password" # PASSWORD
MyHOST="localhost" # Hostname
Password="" #Linux Password
MYSQL="$(which mysql)"
if [ -z "$MYSQL" ]; then
echo "Error: MYSQL not found"
exit 1
fi
MYSQLADMIN="$(which mysqladmin)"
if [ -z "$MYSQLADMIN" ]; then
echo "Error: MYSQLADMIN not found"
exit 1
fi
CHOWN="$(which chown)"
if [ -z "$CHOWN" ]; then
echo "Error: CHOWN not found"
exit 1
fi
CHMOD="$(which chmod)"
if [ -z "$CHMOD" ]; then
echo "Error: CHMOD not found"
exit 1
fi
GZIP="$(which gzip)"
if [ -z "$GZIP" ]; then
echo "Error: GZIP not found"
exit 1
fi
CP="$(which cp)"
if [ -z "$CP" ]; then
echo "Error: CP not found"
exit 1
fi
MV="$(which mv)"
if [ -z "$MV" ]; then
echo "Error: MV not found"
exit 1
fi
RM="$(which rm)"
if [ -z "$RM" ]; then
echo "Error: RM not found"
exit 1
fi
RSYNC="$(which rsync)"
if [ -z "$RSYNC" ]; then
echo "Error: RSYNC not found"
exit 1
fi
MYSQLBINLOG="$(which mysqlbinlog)"
if [ -z "$MYSQLBINLOG" ]; then
echo "Error: MYSQLBINLOG not found"
exit 1
fi
# Get data in dd-mm-yyyy format
NOW="$(date +"%d-%m-%Y-%T")"
DEST="/home/db-backup"
mkdir $DEST/Increment_backup.$NOW
LATEST=$DEST/Increment_backup.$NOW
$MYSQLADMIN -u$MyUSER -p$MyPASS flush-logs
newestlog=`ls -d /usr/local/mysql/data/mysql-bin.?????? | sed 's/^.*\.//' | sort -g | tail -n 1`
echo $newestlog
for file in `ls /usr/local/mysql/data/mysql-bin.??????`
do
if [ "/usr/local/mysql/data/mysql-bin.$newestlog" != "$file" ]; then
echo $file
$CP "$file" $LATEST
fi
done
for file1 in `ls $LATEST/mysql-bin.??????`
do
$MYSQLBINLOG $file1>$file1.$NOW.sql
$GZIP -9 "$file1.$NOW.sql"
$RM "$file1"
done
$RSYNC -avz $LATEST /home/rsync-back
- 首先,在 crontab 上安排时没有显示任何错误。我如何知道脚本是否正在运行?
- 其次,在 crontab 中执行 shell 脚本的正确方法是什么。
- 有些博客建议更改环境变量。最好的解决方案是什么
答案1
从 crontab 运行的脚本并不总是具有您通常认为理所当然的相同环境变量...请执行以下操作:
改变
#!/bin/sh
到
#!/bin/sh -x
使用 -x,您可以尝试手动设置 PATH,如果其他方法都失败,甚至启动 /etc/profile。
#!/bin/sh -x
PATH=/bin:/sbin:/usr/bin:/usr/sbin
/bin/sh /etc/profile
答案2
/bin/sh 版本的 shell 不支持 $(...) 结构。最佳做法是执行以下操作之一:
1. 将 shebang 行更改为 #!/bin/bash
2. 将 crontab 命令更改为 */1 * * * * /bin/bash /home/db-backup/mysqlbackup.sh
3. 1 和 2 均执行。
答案3
尝试导出路径和变量,在 crontabs 中必须指定路径,你执行的方式很好,StackO 和 serverfault 上有很多帖子,你可以在其中找到此问题的答案
答案4
从 cron 运行脚本时可能未设置所需的环境变量。尝试:
*/1 * * * * . /etc/profile; /home/db-backup/mysqlbackup.sh >>/tmp/mysqlbackup.log 2>&1
这意味着在实际备份之前,首先通过运行默认配置文件脚本来设置环境。此外,最后将 STDOUT 和 STDERR 重定向到日志文件。
查找 /var/log/cron 或类似文件。根据您的 *nix 风格,日志也可能位于 .../messages 或 .../syslog 中。cron
在 /etc/syslog.conf 中查找确切配置。
希望这有帮助:-)