1

作为一个 shell 脚本的初学者,我编写了这个 bash 脚本函数来返回文件的 md5sum,同时为用户提供一个 GUI 进度条。

md5sum_of_file () {
    (pv -n $1 | md5sum | sed -e 's/\s.*//g' > /tmp/md5sum) 2>&1 | zenity --progress --auto-close
    echo $(</tmp/md5sum)
    rm /tmp/md5sum
}

pv -n $1将文件输入md5sum | sed -e 's/\s.*//g'(sed 去除总和的关联文件名的输出),同时将百分比传送到zenity --progress --auto-close.

我知道在这种情况下你不能简单地将校验和分配给一个变量,因为“(pv -n $1 | $(md5sum | sed -e 's/\s.*//g'))”在它自己的范围内子壳。但是有没有办法在不创建临时文件(在本例中为“/tmp/md5sum”)的情况下做到这一点?

谢谢。

4

2 回答 2

2

唯一zenity使用的是来自 的标准错误pv,因此使用进程替换来执行此操作,而不涉及来自其他命令的任何 stdout 或 stderr。这可以让输出sed简单地转到标准输出,而不需要任何临时文件。

pv -n "$1" 2> >(zenity --progress --auto-close) | md5sum | sed -e 's/\s.*//g'
于 2014-11-15T18:07:23.310 回答
1

我想这会做(使用 Bash):

md5sum_of_file() {
    local md5sum
    read -r md5sum _ < <( { { pv -n "$1" | md5sum >&3; } 2>&1 | zenity --progress --auto-close; } 3>&1)
    echo "$md5sum"
}

我们在这里做一些管道:

  • pv的标准输出(即文件的内容)通常传递给md5sum,并且md5sum的输出被重定向到文件描述符 3;
  • 然后将标准错误流pv重定向到要馈送到的标准输出zenity
  • 在此之后,我们将文件描述符 3(记住,它的md5sum输出)重定向到标准输出,以供read;
  • read只读取第一个字段(这样我们就不需要sed剪切文件名);
  • 最后,我们echo的结果。

如果您的函数只这样做(也就是说,您只想要echomd5 总和),您也可以这样做:

md5sum_of_file() {
    { { pv -n "$1" | md5sum >&3; } 2>&1 | zenity --progress --auto-close; } 3>&1 | { read -r md5sum _; echo "$md5sum"; }
}
于 2014-11-15T17:11:20.083 回答