我正在用bash编写一个自定义备份脚本供个人使用。目标是通过 tar/gzip 压缩目录的内容,拆分压缩存档,然后将部分上传到 AWS S3。
几个月前,在我第一次尝试编写此脚本时,我能够通过以下内容使其工作:
tar -czf - /mnt/STORAGE_0/dir_to_backup | split -b 100M -d -a 4 - /mnt/SCRATCH/backup.tgz.part
aws s3 sync /mnt/SCRATCH/ s3://backups/ --delete
rm /mnt/SCRATCH/*
这很适合我的目的,但需要/mnt/SCRATCH
有足够的磁盘空间来存储压缩目录。现在我想改进这个脚本,使其不必依赖于在/mnt/SCRATCH
中有足够的空间,并做了一些研究。我最终得到了这样的东西:
tar -czf - /mnt/STORAGE_0/dir_to_backup | split -b 100M -d -a 4 --filter "aws s3 cp - s3://backups/backup.tgz.part" -
这几乎有效,但是我的 S3 存储桶上的目标文件名不是动态的,它似乎只是在运行时多次覆盖backup.tgz.part
文件。最终结果只是一个 100MB 的文件,而预期的几个 100MB 文件结尾为 .part0001
.
任何指导将不胜感激。谢谢!
split
时,您可以使用 env 变量$FILE
来获取生成的文件名。请参阅拆分手册页:
--filter=COMMAND
write to shell COMMAND; file name is $FILE
对于您的用例,您可以使用如下所示的内容:
--filter 'aws s3 cp - s3://backups/backup.tgz.part$FILE'
(需要单引号,否则环境变量替换将立即发生(
这将在 aws 上生成以下文件名:
backup.tgz.partx0000
backup.tgz.partx0001
backup.tgz.partx0002
...
完整示例:
tar -czf - /mnt/STORAGE_0/dir_to_backup | split -b 100M -d -a 4 --filter 'aws s3 cp - s3://backups/backup.tgz.part$FILE' -
你应该能够使用 GNU Parallel 轻松并行地完成它。它具有--pipe
选项,可将输入数据拆分为大小--block
的块,并将其分布在多个并行进程中。
因此,如果要使用 100MB 块并并行使用 CPU 的所有内核,并将块号 ( {#}
( 附加到 AWS 上的文件名末尾,您的命令将如下所示:
tar czf - something | parallel --pipe --block 100M --recend '' aws s3 cp - s3://backups/backup.tgz.part{#}
您可以仅使用 4 个 CPU 内核,而不是所有具有 parallel -j4
的内核。
请注意,我将"记录结束">字符设置为无,这样它就不会试图避免拆分中行,这是它的默认行为,并且比压缩包等二进制文件更适合文本文件处理。