On Sunday 29th April 2012, I have described How to check dd’s progress using User-defined signal 1.
Today, I will extend this topic further using the proc filesystem.
The idea
This technique reads and parses the IO statistics file for running the dd process.
This file is described in detail in section 3.3 [/proc/
the /proc filesystem documentation.
Print how much data has been written to the file or device
$ ./dd.sh if=infile of=outfile 1 GB
This is the simplest solution as it only prints how much data has been written in human-readable form.
#!/bin/sh # print how much data has been written to the file or device # dd output will overwrite printed data at the end # # sample usage: # dd.sh if=infile of=outfile # execute dd command in the background $(which dd) $* & # read process ID process=$! # execute until the process exists while [ "$(kill -0 $process 2>/dev/null; echo $?)" -eq "0" ]; do if [ -e "/proc/${process}/io" ]; then # get number of written bytes written_data=$(cat /proc/${process}/io | awk '/wchar/ {print $2}') # convert it to human readable form unit="B" # bytes if [ "$written_data" -gt "1024" ]; then written_data=$(expr $written_data / 1024) # kilobytes unit="KB" fi if [ "$written_data" -gt "1024" ]; then written_data=$(expr $written_data / 1024) # megabytes unit="MB" fi if [ "$written_data" -gt "1024" ]; then written_data=$(expr $written_data / 1024) # gigabytes unit="GB" fi if [ "$written_data" -gt "1024" ]; then written_data=$(expr $written_data / 1024) # terabytes unit="TB" fi # print output printf "%4s %2s\r" ${written_data} ${unit} # wait 1 second sleep 1 else break fi done
Print how much data has been written to the file or device using a percentage value
$ sh ./dds.sh test test2 67 %
This shell script is different as it prints the percentage value of written data. The most interesting part is that it needs to know the file or device size in advance.
#!/bin/sh # print how much data has been written to the file or device using percentage value # dd output will overwrite printed data at the end # # sample usage: # dds.sh infile outfile # command arguments file_from=$1 file_to=$2 # defaults settings bs="20M" if [ -e "$file_from" ]; then if [ -b "$file_from" ]; then file_from_size=$(blockdev --getsize64 $file_from) else file_from_size=$(stat --format "%s" $file_from) fi $(which dd) if=${file_from} of=${file_to} bs=${bs} & # read process ID process=$! # execute until the process exists while [ "$(kill -0 $process 2>/dev/null; echo $?)" -eq "0" ]; do if [ -e "/proc/${process}/io" ]; then # get number of written bytes written_data=$(cat /proc/${process}/io | awk '/wchar/ {print $2}') percent=$(expr 100 \* $written_data / $file_from_size) # convert it to human readable form # print output printf "%4s %%\r" ${percent} # wait 1 second sleep 1 else break fi done fi
Print how much data has been written to the file using the percentage bar
$ sh ./ddb.sh test test2 41 % [++++++++++++++++ ]
This shell script uses the technique described in Creating simple bar charts in terminal using an awk blog post to print bar chart.
#!/bin/sh # print how much data has been written to the file or device using percentage value # dd output will overwrite printed data at the end # # sample usage: # ddb.sh infile outfile # command arguments file_from=$1 file_to=$2 # defaults settings bs="20M" # character used to print bar chart barchr="+" # current min, max values vmin=1 vmax=100 # range of the bar graph dmin=1 dmax=40 if [ -e "$file_from" ]; then if [ -b "$file_from" ]; then file_from_size=$(blockdev --getsize64 $file_from) else file_from_size=$(stat --format "%s" $file_from) fi $(which dd) if=${file_from} of=${file_to} bs=${bs} & # read process ID process=$! # execute until the process exists while [ "$(kill -0 $process 2>/dev/null; echo $?)" -eq "0" ]; do if [ -e "/proc/${process}/io" ]; then # get number of written bytes written_data=$(cat /proc/${process}/io | awk '/wchar/ {print $2}') percent=$(expr 100 \* $written_data / $file_from_size) # generate output awk --assign dmin="$dmin" --assign dmax="$dmax" \ --assign vmin="$vmin" --assign vmax="$vmax" \ --assign percent="$percent" \ --assign barchr="$barchr" \ 'BEGIN { x=int(dmin+(percent-vmin)*(dmax-dmin)/(vmax-vmin)); printf "%4i %% [", percent for(i=1;i<=dmax;i++){if(i <= x) printf barchr; else printf " "}; printf "]\r" if(x == dmax) printf "\033[0K" }' # wait 1 second sleep 1 else break fi done fi