从 https://blogs.oracle.com/linux/solving-problems-with-proc-v2 上看到的。
pv 能够显示数据处理的进度,非常神奇。而借助 /proc/$pid/fdinfo/$fd
我们能够用 shell 实现类似的功能。
我们都知道在 /proc/$pid/fd/
中可以察看各个进程打开的文件描述符实际指向的文件,
而今天我才知道,原来在 /proc/$pid/fdinfo/
目录下我们还能查看各个文件描述符的状态信息
for fdinfo in /proc/$(pgrep emacs)/fdinfo/*
do
echo ---------------${fdinfo}----------------
cat ${fdinfo}
done |head -n 20
这些信息的意义可以通过 man 5 proc
来获得,其中 pos
表示的是文件的偏移位置。
因此我们可以实现一个简陋的pv
#!/usr/bin/env bash
file="$1"
cat <"${file}" & # 文件内容输出到stdout,这样方便通过管道传递出去.
pid=$!
fd=/proc/${pid}/fd/0
fdinfo=/proc/${pid}/fdinfo/0
size=$(stat --format=%s "${file}") # 获取文件的总大小
while [ -e ${fd} ]; do
progress=$(cat ${fdinfo} | grep ^pos | awk '{print $2}') # 获取偏移量
echo $((100*${progress} / ${size})) # 计算百分比
sleep 0.1
done | dialog --gauge "Progress reading ${file}" 7 100 >&2 # 进度条输出到stdout
效果如下图所示: