Skip to content
Advertisement

How to know when dd has finished

I have a issue with the dd comand. I use it in a while like this:

while c=$(dd count=1000 bs=1 2>/dev/null) ;do

    echo -n "$c" > /dev/ttyO5
done < $FILE

And it works like charm, the only problem is that once the file is read completely, it doesnt stop the while, it stays there stalled. How could I make the while to stop once the dd read all the file?

BTW: Note my machine is embed linux, it doesnt have all the comands and tools as a normal ubuntu machine would have.

Thanks

Output dd --version

BusyBox v1.20.2 (MUSE) multi-call binary.

Usage: dd [if=FILE] [of=FILE] [bs=N] [count=N] [skip=N]
        [seek=N]

Copy a file with converting and formatting

        if=FILE         Read from FILE instead of stdin
        of=FILE         Write to FILE instead of stdout
        bs=N            Read and write N bytes at a time
        count=N         Copy only N input blocks
        skip=N          Skip N input blocks
        seek=N          Skip N output blocks

Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),
MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)

Advertisement

Answer

Note

  • ” will be lost after assigning to a variable.
  • ‘\’ may keep its special meaning depending on version of echo : try echo 'n'

Status can be retrieved reading from stderr

dd count=1000 bs=1 </dev/null
0+0 records in
0+0 records out

So

while
    c=$(dd ... 2>errorfile); 
    read line <errorfile;   # read the first line of error
    [[ $line != 0+0* ]];    # break while if line begins with 0+0
do
    ...
done

It’s slightly different from checking from length of c

c=$(dd count=1 bs=1 </dev/null)
echo "${#c}"


c=$(dd count=1 bs=1 <<<$'')
echo "${#c}"

because in the last case a NUL character was read whereas in the previous no character were read.

EDIT: following demonstrates that it works but is very slow :

for x in {{0..9},{a..f}}{{0..9},{a..f}}; do printf "x$x"; done |
while
    c=$(dd count=1 bs=1 2>errfile;echo .); c=${c%.}
    read line <errfile
    [[ $line != 0+0* ]]
do
    if [[ $c = '' ]]; then printf ""; else echo -n -E "$c"; fi
done | od -c
Advertisement