如何从bash逐行执行MySQL命令并捕获输出?

时间:2017-04-20 20:52:00

标签: mysql linux bash

如果有替代bash的话,我也会很感激。

我有一大堆MySQL命令(超过10 GB)

恢复转储时,我会收到一些警告,偶尔也会出错。我需要执行这些命令并处理所有警告和错误。而且,最好自动完成。

mysql --show-warnings
tee logfile.log
source dump.sql

日志文件将包含许多行,告诉每个命令是否成功,并将显示一些警告,特别是截断列。但原始文件有数万个非常大的INSERT s,日志不是特别有用。尽管它需要某种监督互动。 (例如,我无法编程crontab。)

#!/bin/bash
echo "tee logfile.log" > script.sql
echo "source $1" > script.sql
mysql --show-warnings < script.sql > tmpfile.log 2>&1
cat tmpfile.log >> logfile.log

tee命令在此批处理环境中不起作用。我可以捕获所有警告,但我无法确定哪个命令产生了每个警告。

所以我得到了这个小小的讽刺:

#!/bin/bash
ERRFILE=$(basename "$0" .sh).err.log
LOGFILE=$(basename "$1" .sql).log
log_action() {
    WARN=$(cat)
    [ -z "$WARN" ] || echo -e "Line ${1}: ${WARN}\n${2}" >> "$LOGFILE"
}
echo 0 > "$ERRFILE"
log_error() {
    ERNO=$(cat "$ERRFILE")
    ERR=$(cat)
    [ -z "$ERR" ] || echo -e "*** ERROR ***\nLine ${1}: ${ERR}\n${2}" >> "$LOGFILE"
    (( ERNO++ ))
    echo $ERNO > "$ERRFILE"
}
COUNT=0
COMMAND=''
echo -e "**** BEGIN $(date +%Y-%m-%d\ %H:%M:%S)\n" > "$LOGFILE"
exec 4> >(log_action $COUNT "$COMMAND")
exec 5> >(log_error $COUNT "$COMMAND")
exec 3> >(mysql --show-warnings >&4 2>&5)
while IFS='' read -r LINE || [[ -n "$line" ]]
do
    (( COUNT++ ))
    [ ${#LINE} -eq 0 ] && continue          # discard blank lines
    [ "${LINE:0:2}" = "--" ] && continue    # discard comments
    COMMAND+="$LINE"                        # build command
    [ "${LINE: -1}" != ";" ] && continue    # if not finnished keep building
    echo $COMMAND >&3                       # otherwise execute
    COMMAND=''
done < "$1"
exec 3>$-
exec 5>$-
exec 4>$-
echo -e "**** END $(date +%Y-%m-%d\ %H:%M:%S)\n" >> "$LOGFILE"
ERRS=$(cat "$ERRFILE")
[ "ERRS" = 0 ] || echo "${ERRS} Errors." >&2

这将扫描$1处的文件,并将命令发送到&amp; 3处的打开MySQL连接。那部分工作正常。

警告和错误的捕获无效。

  1. 它只记录第一个错误。
  2. 它只记录第一个警告。
  3. 我找不到将行号$COUNT和违规命令$COMMAND传递给录音功能的好方法。
  4. 唯一的错误是在时间戳之后,唯一的警告是在错误之后,这不是脚本的时间顺序。

0 个答案:

没有答案