6

I'm debugging a binary stream that is coming from a device file. I would like to have the output printed out in real time as hex values.

So far I've used tail -f /dev/ttyAPP2 | hexdump -C but after I started missing some bytes in the output I understood that this could be a bad choice because it doesn't flush the data until a newline character is found.

There is an unofficial binary tail but I currently can't use that approach and am looking for a suggestion how to achieve this with other means?

Example

First the tty is set to raw mode.

stty -F /dev/ttyAPP2 raw

Here is what I get when listening to the device (this is real output)

root@Vdevice:/dev# hexdump -C < /dev/ttyAPP2
00000000  55 00 21 00 02 26 00 02  0b 00 09 02 06 01 00 01  
00000010  99 0c ec 45 4f 01 03 47  41 54 45 57 41 59 43 54 

However, the expected package should be (this isn't a real output):

root@Vdevice:/dev# hexdump -C < /dev/ttyAPP2
00000000  55 00 21 00 02 26 00 02  0b 00 09 02 06 01 00 01  
00000010  99 0c ec 45 4f 01 03 47  41 54 45 57 41 59 43 54  
00000020  52 4c 00 00 00 00 00 8b  

The other part of the package gets printed out on arrival of the second package (this is real output)

root@Vdevice:/dev# hexdump -C < /dev/ttyAPP2
00000000  55 00 21 00 02 26 00 02  0b 00 09 02 06 01 00 01  
00000010  99 0c ec 45 4f 01 03 47  41 54 45 57 41 59 43 54
00000020  52 4c 00 00 00 00 00 8b  55 00 21 00 02 26 00 02
00000030  0b 00 09 02 06 01 00 01  99 0c ec 45 4f 01 03 47
00000040  41 54 45 57 41 59 43 54  52 4c 00 00 00 00 00 8b
9
  • does od -x < /dev/ttyAPP2 have the right format?
    – Jeff Schaller
    Feb 3, 2016 at 16:07
  • sounds like xxd /dev/ttyAPP2 might be what you're looking for
    – djf
    Feb 3, 2016 at 16:10
  • Interacting directly with the device like this can create unintentional blocking on the original stream, which probably isn't desirable as this will interfere with the data flow you're trying to observe. It may be better to trace the process already reading the device file and capture the data as its read by that process. What is doing the reading of that binary stream? Feb 3, 2016 at 16:24
  • 1
    tail -f is rarely useful for files other than regular files. Why aren't you using </dev/ttyAPP2 hexdump -C ? Feb 3, 2016 at 22:00
  • 1
    @Alan It only stops if it reaches the end of file. That doesn't usually happen with devices. Can't you configure your device not to send EOF, as explained in mikeserv's answer? Feb 4, 2016 at 11:11

2 Answers 2

7

You don't need to tail -f a tty. If it's sending you EOF, or, if it is line-buffering, then you need to configure it.

stty -F/dev/ttyAPP2 raw

Now you can...

cat /dev/ttyAPP2

...as needed...

You might try...

</dev/ttyAPP2 \
dd bs=16 conv=sync | od -vtx1

...which will sync out every successful read() from your device into 16-byte, null-padded blocks, and so will write line-buffered output (such as to your terminal) in real-time regardless of throughput, though any trailing nulls might distort your stream.

With GNU stdbuf and a dynamically linked od:

stdbuf -o0 od -vtx1 </dev/ttyAPP2

...would write output in real-time regardless.

You might also buffer to a temp file like...

f=$(mktemp)
exec 3<>"$f"; rm -- "$f"
while   dd >&3 of=/dev/fd/1 bs=4k count=1
        [ -s /dev/fd/3 ]
do      od -An -vtx1 /dev/fd/3
        echo
done    </dev/ttyAPP2 2>/dev/null

...which, though likely not nearly as efficient as the other recommendations, might be worth considering if you wanted to delimit reads from your device by EOF. I find the technique useful sometimes when working with ttys, anyway.

It is also possible to force hexdump to print out less bytes by using the custom print format. The example below will print every time there are 4 bytes available:

hexdump -e '4/1 "%02x " "\n"' < /dev/ttyAPP2

5
  • I've updated the question. ...which will sync out every successful read() from your device seems like it could be an issue with the tty buffer size Feb 4, 2016 at 11:52
  • @Alan.... no. Its to do with od's output buffer, actually. See how there are 16 bytes per line there? hexdump (though you'd do better w/ od) will do 16 bytes per line and it will write output to a terminal one line at a time. dd doesn't have that problem, and it writes output as soon as it arrives. But in order to flush od's output in the same way, you've got to block out at 16 bytes per dd write - which is what dd is used for there. Any input shy of 16 bytes will get null-padding to equal 16, and so od will always write a line of output as soon as any input is available.
    – mikeserv
    Feb 4, 2016 at 12:07
  • @Alan - or you could use one of the other two options as well. stdbuf is a likely candidate. GNU od also has the -width setting - you could do -w1, for example, and write a line per byte.
    – mikeserv
    Feb 4, 2016 at 12:12
  • Great reasoning, thank you :) I will do some research on it and once I get the proof of concept running will accept the answer. I'm in bad luck to be running busybox versions of dd and od on the platform :p Feb 4, 2016 at 13:01
  • @Alan - yeah, you are. you should fix that. busybox has horrible versions of those utilities. get toybox.
    – mikeserv
    Feb 4, 2016 at 13:09
2

if multiline (9 lines) solution is ok, check below hextail.sh script:

#!/usr/bin/env bash

#par1==buffsize, par2=xxd-columns-width, par3=sleepVal;    defaults: 256 16 0
size=${1:-256}; cols=${2:-16}; cnt=0; hbuff=$(eval printf '00%.0s' {1..$size})
while true; do
   hbuff=${hbuff:2}$(dd bs=1 count=1 2>/dev/null | xxd -p) #shiftLeft, add 1b
   printf '\033[;H'; xxd -r -p <<<$hbuff | xxd -g1 -c$cols #cursor gotoxy 1,1
   echo total bytes: $((++cnt)) ;   [ -z $3 ] || sleep $3  #...and buff show.
done

it implements binary tail by storing its hex representation in bash string variable. First byte in buff deleted on appending new byte at the end.

example test commands:

1) cat /dev/urandom | ./hextail.sh 1024 32 0.2      ...with 200ms sleep
2) ./hextail.sh < /dev/ttyAPP2
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.