用好bash管道和重定向,让数据备份更高效

在日常运维中,数据备份是再平常不过的事。你可能每天都要把日志、配置文件或数据库导出打包,传到另一个位置。手动复制粘贴显然不现实,这时候bash的管道和重定向就是你的趁手工具。

重定向:控制输入输出的流向

默认情况下,命令从键盘读取输入,结果输出到屏幕。重定向让我们能改变这个路径。比如,把某个命令的结果保存到文件,而不是盯着终端一行行看。

最常用的重定向符号是 >>>。前者会覆盖目标文件,后者则是追加内容。

ls /var/log > log_files.txt

这条命令把目录列表写进 log_files.txt。如果文件已存在,内容会被清空重写。如果你只是想追加今天的备份记录:

date >> backup_log.txt

这样每次运行都会在文件末尾加上当前时间,日志越积越多,方便后续查看。

还有一种情况:你只想执行命令,但不想看到任何输出。比如定时任务跑备份脚本,成功时没必要发邮件提醒。这时候可以把输出扔进“黑洞”:

tar czf backup.tar.gz /data > /dev/null 2>&1

这里 /dev/null 是个特殊设备,所有写进去的数据都消失不见。2>&1 表示把错误输出(stderr)也重定向到标准输出(stdout),一起吞掉。

管道:让命令串起来干活

单个命令功能有限,但通过管道 |,可以把一个命令的输出直接交给下一个处理。就像流水线,每个环节只干一件事,组合起来却很强大。

比如你想查看最近修改过的前5个备份文件:

ls -lt /backups | head -6

ls -lt 按修改时间排序列出文件,输出传给 head -6,取前6行(第一行是总用量,所以取6行得到5个文件)。

再举个实际场景:你要把 MySQL 数据库导出并压缩,但服务器磁盘紧张,不能先存 SQL 再压缩。解决方案?用管道一步到位:

mysqldump mydb | gzip > mydb_$(date +%F).sql.gz

这里 mysqldump 生成的 SQL 不会落地,直接通过管道送给 gzip 压缩,最终写入带日期的压缩文件。整个过程内存完成,节省空间。

结合使用:构建可靠备份流程

真实环境中,往往需要管道和重定向配合。比如你写了个备份脚本,希望记录运行状态,同时出错时能及时发现。

#!/bin/bash
DUMP_FILE="/backup/db_$(date +%H%M).sql.gz"

mysqldump myapp | gzip > "$DUMP_FILE" 2> /tmp/backup.err

if [ $? -ne 0 ]; then
    echo "[ERROR] 备份失败,详情见 /tmp/backup.err" >&2
    exit 1
fi

echo "[OK] 已生成备份:$DUMP_FILE" >> /var/log/backup.log

这个脚本把标准输出压缩后写入目标文件,错误信息单独捕获到临时文件。如果命令失败,就从错误文件读取原因,并向 stderr 输出提示。成功则往日志追加一条记录。

再进一步,你可以把整个流程塞进 cron 定时任务,每天凌晨自动跑一遍。只要检查日志和目标目录,就能确认数据有没有乖乖备份。

熟练掌握管道和重定向,不只是省几行代码的事。它让你用最小代价搭建起稳定、可追溯的备份机制。哪怕机器宕了,心里也踏实——因为你知道,数据早就安静地躺在另一个角落。