watch + lsof == Instant Progress Bar

Não sei sobre você, mas a maior parte do meu uso direto do Linux industrial se resume à criação de pipelines de shell operando em gigabytes de arquivos de dados. Ocasionalmente, fico ambicioso demais e acabo encarando um terminal sem visão por uma ou duas horas. Como uma criatura preguiçosa e impaciente, isso ofende minhas sensibilidades!

Esses pipelines estão, em última análise, puxando sua entrada do disco e concluindo quando essa entrada se esgota. O kernel com certeza sabe até que ponto esses arquivos foram lidos: podemos apenas perguntar.

Pode-se pesquisar a posição de um descritor de arquivo aberto para leitura com lsof. Isso é ótimo, mas realmente gostaríamos de um HUD descartável que possamos verificar ocasionalmente entre os episódios do Bob Esponja. O relógio pode nos ajudar nisso; e ao colocar os dois juntos podemos fazer um doohick:

function watch_progress {
local file=$1
local size=`sudo du -b $file | awk '{print $1}'`
local pid=${2:-`
sudo lsof -F p $file | cut -c 2- | head -n 1

`
}

local watcher=/tmp/watcher-$$
cat
<<EOF > $watcher
file
=$file
size
=$size
pid
=$pid
EOF


cat
<<'EOF' >> $watcher
line
=`sudo lsof -o -o 0 -p $pid | grep $file`
position
=`echo $line | awk '{print $7}' | cut -c 3-`
progress
=`echo "scale=2; 100 * $position / $size" | bc`
echo pid $pid reading $file
: $progress% done
EOF


chmod
+x /tmp/watcher-$$
watch
/tmp/watcher-$$
}

Então

watch_progress input-file

..para uma leitura instantânea do progresso ^ _ ^.