计算设备全部内容的校验和并添加进度条

计算设备全部内容的校验和并添加进度条

我想制作一个 shell 脚本,让用户选择已安装的设备并计算该设备上全部数据的校验和。我需要校验和来测试设备是否已被其他人操纵。我的方法如下:

#!/bin/bash
cd "${0%/*}"



device=$(zenity --file-selection --directory \
--filename="/run/media/"${USER}"/"


zenity --info \
--title "Info Message" \
--width 500 \
--height 150 \
--text "$(find "$device" -type f -exec md5sum {} \; | sort -k 2 | md5sum | cut -d ' ' -f 1)"

我的问题是:

  1. 这是正确的方法吗?
  2. 如何在设备选择和计算输出对话框之间添加进度条?

答案1

您可以使用pv它允许您通过管道监视数据的进度。

find "$device" -type f -exec md5sum {} \; | pv -ls $(find "$device" -type f |wc -l) | sort -k 2 | md5sum
  • -s <size>提供数据的总大小。由于我们要根据文件数量显示进度,需要知道设备中有多少个文件,因此$(find "$device" -type f |wc -l).
  • -l- 不计算字节数,而是计算行数(换行符)。

第一个find命令将 md5sum 的结果发送到该pv命令。pv将计算完成的百分比(输入行数除以标志提供的总大小-s),它将向对话框写入终端的标准错误,并将其输入(第一个命令的结果find)发送到该命令之后的下一个命令管道(在本例中为sort)。

$ find "$device" -type f -exec md5sum {} \; | pv -ls $(find "$device" -type f |wc -l) | sort -k 2 | md5sum | cut -d ' ' -f 1
6.77k 0:00:10 [1.61k/s] [=========>                            ] 28% ETA 0:00:24

如果设备上的文件太多,统计文件数量也可能需要很长时间,则可以直接使用pv -l,此时不会显示完成百分比和预计到达时间,并且进程栏会向左移动并显示正确仅表明数据正在移动。

$ find "$device" -type f -exec md5sum {} \; | pv -l  | sort -k 2 | md5sum | cut -d ' ' -f 1
5.64k 0:00:09 [1.72k/s] [        <=>                                           ]

为了在zenity窗口中显示进度条,您可以执行以下操作:

find "$device" -type f -exec md5sum {} \; \
| ( ( pv -nls $(find "$device" -type f |wc -l) 2>&1 1>&3 ) \
| zenity --progress --auto-close --text="md5sum progress..." 2>/dev/null ) 3>&1 \
| sort -k 2 | md5sum | cut -d ' ' -f 1
  • -nflag for pv- 不会给出进度的视觉指示,而是pv给出标准错误的整数百分比,每行一个。
  • 2>&1stderr会将命令的号pv(百分比计数)重定向到命令的stdout-号,因此后者可以读取百分比计数并显示进度条。stdinzenity
  • 1>&3将旧文件stdout(命令的输出find ... md5sum)重定向到新文件描述符 3,以将其与stdin进程的文件描述符分开zenity
  • 3>&1将进程的文件描述符 3 pv(包含命令的输出find)重定向回stdout,这是命令stdinsort继续分析。

如果您想md5sum在另一个zenity窗口中查看最终输出:

zenity --info \
--title "Info Message" \
--width 500 \
--height 150 \
--text \
"$(find "$device" -type f -exec md5sum {} \; \
| ( ( pv -nls $(find "$device" -type f |wc -l) 2>&1 1>&3 ) \
| zenity --progress --auto-close --text="md5sum progress..." 2>/dev/null ) 3>&1 \
| sort -k 2 | md5sum | cut -d ' ' -f 1)"

相关内容