仅当 mysqldump 不出错时如何进行 gzip?

仅当 mysqldump 不出错时如何进行 gzip?

当且仅当 mysqldump 不产生任何错误时,我想压缩 sql 转储。我尝试输入错误的密码,但它仍然执行 gzip。

 mysqldump -u username -ppassword dbname |& if [ $? == 0 ]; then gzip > test.gz; else echo "error"; fi

我的命令有什么问题或者有更好的解决方案吗?

答案1

我认为你可以删除|&(原因是你不需要将 stdout 或 stderr 通过管道传输到下一个条件,如果有的话,你可以使用 ';' 作为命令分隔符)。像这样的东西可能应该有效:

#!/bin/bash
mysqldump -u myuser -p mypasswd > mydb.dump
if [[ $? -eq 0 ]]; then
    gzip mydb.dump
else 
    echo >&2 "DB backup failed" 
    exit 1
fi

编辑:要检查 gzip 是否成功,您可以执行以下操作:

mysqldump -u myuser -p mypasswd | gzip > mydb.dump.gz && echo "success" || echo "failure" 

然而,即使mysqldump失败,即如果备份因除 gzip 填充磁盘之外的大多数原因而失败,这也会报告成功。

答案2

你也可以

mysqldump -someparams dump.sql && gzip dump.sql || echo "Backup failed"  

或者

mysqldump -someparams dump.sql  
[[ $? == 0 ]] && gzip dump.sql || echo "Backup failed "

答案3

管道并行执行两侧。您尝试执行此操作的方式在概念上是不可能的:mysqldump如果您与 的执行并行执行此测试,则在命令完成之前您无法测试命令的状态mysqldump。您需要运行mysqldump,等待它完成,然后然后决定是否跑步gzip

由于mysqldump必须完成运行,因此它的输出必须到达某个地方。大概您希望输出很大,因为您正在压缩它。因此,明智的选择是对其进行压缩。因此无条件压缩输出。

mysqldump -u username -ppassword dbname | gzip > test.gz

注意,我用的是|,而不是|&。在这里使用|&是没有意义的:如果有任何错误消息,它们最终会与转储混合在一起,并且不可能恢复转储。

尚待解决的问题是检测是否mysqldump成功。假设这是一个 bash 或 ksh 脚本(即它以#!/bin/bashor#!/bin/ksh等​​开头,而不是以 开头#!/bin/sh),设置pipefail选项,以便管道在任何部分发生故障时也会发生故障。 (默认情况下,管道的状态是其最右边命令的状态,其他命令的状态将被忽略。)

#!/bin/bash
set -o pipefail -o errexit
tmp="mydump.tmp.$$.gz"
trap 'rm -f "$tmp"' ERR INT TERM HUP
mysqldump … | gzip >"$tmp"
mv "$tmp" mydump.gz

设置该errexit选项可确保如果管道失败,则脚本会在该点退出(与管道具有相同的错误状态)。因此,mydump.gz仅当转储成功时才会创建名为的文件。该trap命令设置一个陷阱,以便如果脚本失败或被列出的信号之一终止,则临时文件将被删除。

答案4

如果您想避免使用临时文件,另一个解决方案是在出错时删除生成的文件:

( mysqldump ... || rm -f test.gz ) | gzip > test.gz

或者,如果您想要一个明确的标志,如下所示:

rm -f test.ok
( mysqldump ... && touch test.ok ) | gzip > test.gz
if [[ $? -eq 0 && -r test.ok ]]; then
    echo it worked
else
    echo something went wrong
fi

相关内容