我正在用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
结尾。
任何指导将不胜感激。谢谢!
答案 0 :(得分:1)
使用split
时,可以使用env变量$FILE
来获取生成的文件名。
参见split man page:
--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' -
答案 1 :(得分:1)
您应该能够使用 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
的所有内核。
请注意,我将“记录末尾” 字符设置为空,以便它不会尝试避免分割中线,这是它的默认行为,比二进制文件更适合于文本文件处理像tarball。