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

jfugit 发布于 2019-03-09 bash 最后更新 2019-03-09 14:35 3 浏览

我在循环中转储数据库,如果我尝试并转储不存在的数据库,我会像我期望的那样得到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有关,但作为一个C#开发人员试图学习bash,我被卡住了!
已邀请:

taut

赞同来自:

那是因为$?会给你上次执行的命令的返回状态,在这种情况下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

hid

赞同来自:

你想检查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=${PIPESTATUS[0]}而不是result=$?

gipsam

赞同来自:

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

($dumpcmd $database || echo "$dumpcmd exited with $?" 1>&2) | (gzip > "$backupdir/$database.gz" || echo "echo exited with $?" 1>&2)
或者您可以在脚本开头set -o pipefail使管道的返回状态为最后(最右侧)命令的值以非零状态退出,如果管道中的所有命令都成功退出,则返回零。