2

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

我的代码如下:

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

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

4

3 回答 3

6

你想检查里面有什么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]}

于 2013-04-11T17:10:30.157 回答
1

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

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

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

于 2013-04-11T16:27:15.940 回答
1

那是因为$?会给你最后执行的命令的返回状态,在这种情况下 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
于 2013-04-11T16:11:23.863 回答