mysqldump | gzip - $?始终设置为0

时间:2013-04-11 16:09:26

标签: bash

我在循环中转储数据库,如果我尝试转储不存在的数据库,我会得到stderr mysqldump: Got error: 1049: Unknown database 'yes' when selecting the database,但是尽管错误$?总是返回0。

我的代码如下:

for database in ${databases[@]}; do
    $dumpcmd $database | gzip > "$backupdir/$database.gz"
    result=$?
    echo "dumped database: $database ($result)"
done

我想从mysqldump中检测到一个错误并将其打印到屏幕上 - 我有预感这与gzip的管道有关,但作为一个试图学习bash的C#dev我被卡住了!

3 个答案:

答案 0 :(得分:5)

您想查看PIPESTATUS中的内容:

   PIPESTATUS
          An  array  variable (see Arrays below) containing a list of exit
          status values from the processes in  the  most-recently-executed
          foreground pipeline (which may contain only a single command).

因此,请尝试result=$?

而不是result=${PIPESTATUS[0]}

答案 1 :(得分:1)

那是因为$?会给你 last 执行命令的返回状态,在这种情况下gzip是什么。但gzip不关心mysqldump错误消息。它们只是常规的文本输出,可以压缩。

将您的示例更改为类似内容,以了解mysqldump的返回状态:

for database in ${databases[@]}; do
    # dump to a temporary file
    $dumpcmd $database > temp.sql
    # check mysqldump's return status
    result=$?
    if [ $result != 0 ] ; then
        echo "mysqldump error"
        exit 1
    fi
    gzip temp.sql > "$backupdir/$database.gz"
    echo "dumped database: $database ($result)"
done

答案 2 :(得分:1)

您可以使用它来确保在执行zip之前转储有效:

($dumpcmd $database || echo "$dumpcmd exited with $?" 1>&2) | (gzip > "$backupdir/$database.gz" || echo "echo exited with $?" 1>&2)

或者您可以在脚本开头set -o pipefail使管道的返回状态为最后(最右侧)命令的值以非零状态退出,如果管道中的所有命令退出,则返回零成功。