Solved dd can't open a device and output to stdout?

I issued the following dd(1) command in 15.0-BETA1 and it failed:
Code:
# dd if=/dev/cd0 bs=1 count=1352306688 | sha512sum
dd: /dev/cd0: Invalid argument

Yet when I piped stdin to it instead, it succeeded:
Code:
# cat /dev/cd0 | dd bs=1 count=1352306688 | sha512sum
1352306688+0 records in
1352306688+0 records out
df9142b24c50535e27ecd463e1ccd120ab5a8ccd54f7cecb067f24b7cea4ab222eee45c91e735c1b8f1a0484c239734d5ce377671ff50924dd76e9fc83245c82  -
1352306688 bytes transferred in 5590.785396 secs (241881 bytes/sec)

The man page mentions that dd first appeared in AT&T UNIX. So I tried it on my SVR4 system and it succeeded:
Code:
# uname -a
manapua manapua 4.0 4 i386 386/AT
# dd if=/dev/cdrom/cd0 bs=1 count=32768 | sum
32768+0 records in
32768+0 records out
0 64

Similarly, it works in Fedora Linux:
Code:
$ sudo dd if=/dev/cdrom bs=1 count=1352306688 | sha512sum
1352306688+0 records in
1352306688+0 records out
1352306688 bytes (1.4 GB, 1.3 GiB) copied, 4346.49 s, 311 kB/s
df9142b24c50535e27ecd463e1ccd120ab5a8ccd54f7cecb067f24b7cea4ab222eee45c91e735c1b8f1a0484c239734d5ce377671ff50924dd76e9fc83245c82  -

That doesn't make sense to me. Any thoughts?
 
by inference, we'd say that freebsd is barfing because you're trying to access the device at something other a multiple of than its natural block size, and the other kernels are papering over that with some kind of buffering; cat might be working because it naturally requests blocks of the right size. we'd further hazard a guess that the SVR4 system has a raw device wherein bs=1 won't work.
 
but
bc -l
1352306688/2048
660306.00000000000000000000

or if you want it your way do
dd if=/dev/cd0 bs=2048 count=whatever|dd bs=1|md5
 
Hahaha, thank you! I really appreciate the explanations and examples, it wasn't clear to me from the man page.
Code:
# dd if=/dev/cd0 bs=2048 count=660306 | sha512sum
660306+0 records in
660306+0 records out
df9142b24c50535e27ecd463e1ccd120ab5a8ccd54f7cecb067f24b7cea4ab222eee45c91e735c1b8f1a0484c239734d5ce377671ff50924dd76e9fc83245c82  -
1352306688 bytes transferred in 392.789846 secs (3442825 bytes/sec)
I'm sure that the developer had their reasons for this difference in anticipated behaviour. Nevertheless, I find it surprising because this design choice doesn't seem to align with the UNIX philosophy which encourages writing programs that read and write in a stream-oriented, device-independent fashion.
 
Traditionally Unix had "buffered" devices (aka block devices) and "unbuffered" devices (aka character, but also raw block devices). FreeBSD simplified things, so no more block devices and all devices in /dev are unbuffered. If you access devices in /dev directly you must use a device's 'natural' block size. On a mac you will still see e.g. a block device /dev/disk0 and corresponding unbuffered or "raw" character device /dev/rdisk0. Linux as usual made different and (IMHO) more complicated choices.
 
The real fun begins when you start to use tape devices, which can have different blocks size depending on which tape is in the drive ...
 
Back
Top