我正在尝试将大型 LVM 卷的 tar 复制到多个外部驱动器上。这部分已经解决了。现在,由于这是一个漫长的过程,我想要一个进度条。从这里的优秀文章来看,我已经接近目标了。
问题是,第一个卷填满后,PV 栏会停止。我希望 PV 在交换磁盘后继续更新。有人知道如何解决这个问题吗?
这是我尝试过的方法。我认为问题出在最后一行代码上。我不确定这种策略是否真的适用于多卷。
代码 ExtBackup.sh:
#!/bin/sh
changedisk()
{
# This routine is called when tar runs out of disk space
# It simply waits for operator to change and mount disks
# then updates the file handle with a new volume number.
echo "Change disks now!"
read -p "Press <enter> when new disk is mounted. ..." NULL
echo ""
# Update the file name with the new volume number
name=`expr $TAR_ARCHIVE : '\(.*\)-.*'`
echo ${name:-$TAR_ARCHIVE}-Vol$TAR_VOLUME.tar >&$TAR_FD
}
###########
## MAIN ##
###########
# Test for recursive call to change disks
if [ "$1" = 'changedisk' ]; then
changedisk
exit 0;
fi
# If this is initial call, set SIZE to calculate bytes in source
SIZE=`du -sb *Folder_Name* | cut -f 1`
# Now TAR it, using Multi-volume option and pipe through PV for progress bar
tar -cM -F 'sh ExtBackup.sh changedisk' *Folder_Name* | \
pv -s ${SIZE} > LVMBackup-$(date +%m-%d-%y)-Vol1.tar
答案1
好吧,我花了一些时间才明白它tar -F
实际上做了什么(有任何记录吗?我只是读了源代码),但我认为我为你找到了一个非常好的解决方案。
由于pv
不支持假装已经取得了某个进展,我需要用一个类似的工具来替换它bar
(在 Debian 中以这个名字提供,或者看看它可怕的主页)。
我发现的解决方案是将所有附加卷的数据通过命名管道 (FIFO) 传递,以将调用bar
注入流中。为了避免在新行中打印每个卷的进度条,我使用“tput”在每个卷之后将光标移回上部。
在您的代码中,您将用以下内容替换最后一行changedisk()
。(为了简洁起见,这有点不合时宜;一旦您明白了,只需对其进行自定义即可)
tput cuu1 >&2 # clear previous progress bar
(cat somefifo | bar -ns \
--size "$SIZE" \
--completed $(((${TAR_VOLUME}-1)*${VOLSIZE})) \
> ${name:-$TAR_ARCHIVE}-Vol$TAR_VOLUME.tar) &
echo somefifo >&$TAR_FD
并将pv
脚本最后一行的调用替换为bar -ns --size ${SIZE}
。
为了使其工作,您需要将其放在export
SIZE 定义前面,当然还要mkfifo somefifo
事先执行。确保您还保护了 FIFO 的权限位。您可能还想考虑使用mktemp
来安全地创建临时管道。我想这取决于您的情况。
我使用了一个尚未定义的变量$VOLSIZE
,该变量应扩展为卷的大小(以字节为单位)。我不确定在您的设置中如何确定这一点。也许您需要在这里做一些更复杂的事情,例如跟踪所有先前卷大小的累计总和。