views:

1654

answers:

4

Does anyone know how I can read the first two characters from a file, using a bash script. The file in question is actually an I/O driver, it has no new line characters in it, and is in effect infinitely long.

A: 

G'day,

Why not use od to get the slice that you need?

od --read-bytes=2 my_driver

Edit: You can't use head for this as the head command prints to stdout. If the first two chars are not printable, you don't see anything.

The od command has several options to format the bytes as you want.

HTH

cheers,

Rob Wells
or head --bytes=2 my_driver
alex vasi
These soultions would work on a lot of systems, but I'm using an embedded system that doesn't have head or od installed.
Simon Hodgson
You don't have head but all the options to read ? My embedded env does the opposite :) And I often put dd in whatever embedded system I build
shodanex
+4  A: 

The read builtin supports the -n parameter:

     vinko@mithril:~$ echo "Two chars" | while read -n 2 i; do echo $i; done
     Tw
     o
     ch
     ar
     s


     vinko@mithril:~$ cat /proc/your_driver | (read -n 2 i; echo $i;)
Vinko Vrsalovic
Just what I was after - thanks!
Simon Hodgson
may not work as you want if one of the first two bytes are in $IFS, dd will do
PW
True, but there's no other BASH way to do it, as far as I know.
Vinko Vrsalovic
Anyway, as long as you are using a single name, there should be no problems, as $IFS enters the picture when you are splitting the line into more than one name (or variable).
Vinko Vrsalovic
+1  A: 

I think dd if=your_file ibs=2 count=1 will do the trick

Looking at it with strace shows it is effectively doing a two bytes read from the file. Here is an example reading from /dev/zero, and piped into hd to display the zero :

dd if=/dev/zero bs=2 count=1 | hd
1+0 enregistrements lus
1+0 enregistrements écrits
2 octets (2 B) copiés, 2,8497e-05 s, 70,2 kB/s
00000000  00 00                                             |..|
00000002
shodanex
yes, this one is more robust than read -n for binary (especially for bytes within IFS). V=`dd if=/dev/whatever bs=2 count=1 2>/dev/null`
PW
A: 
echo "Two chars" | sed 's/../&\n/g'