1

I need to read a specific number of bytes from fd0 and write them to a file. The bytes can have any value.

I assume I can't use dd since it stops at the EOF byte. Using if=/dev/stdin won't work since my fd0 isn't the keyboard.

AdminBee
  • 22,803
hehehe
  • 13
  • 2
    why would you assume dd stops on an EOF byte? Did you try it? Can you [edit] to show what you did and what happened? – ilkkachu Dec 25 '21 at 22:54
  • 3
    There's no such thing as "the EOF byte" – Philip Couling Dec 25 '21 at 23:16
  • File descriptor 0 is otherwise known as "stdin". /dev/stdin is a (most likely) a symbolic link to /proc/self/fd/0 where /proc/self is a symbolic link that resolves differently for each process. Long story short, /dev/stdin will resolve to whatever file descriptor 0 is for the process resolving it. If /dev/stdin is somehow different for you, you can always use /proc/self/fd/0. – Philip Couling Dec 25 '21 at 23:27
  • 2
    EOF isn't a signal and it isn't "emitted" either. It's just a condition on a file descriptor. – user10489 Dec 26 '21 at 00:53
  • Thanks for clearing this misunderstanding, I thought EOF is a specific byte, which would make sending binary data difficult. – hehehe Dec 26 '21 at 01:06

1 Answers1

0

dd (and many other unix commands) default to taking input from stdin when no input file is supplied.

stdin doesn't have to be a keyboard, and frequently isn't.

The dd command is specifically designed to copy binary data. And even if it wasn't, EOF is not a byte in unix. It is a condition on a file descriptor indicating there is no more data from that source.

From a keyboard (or more to the point, a tty), the Ctrl-D control character is not EOF, but (by default) causes the tty to enter EOF condition, similar to how Backspace causes a character to be removed from the input buffer. Note that this only has meaning when the tty is in cooked mode rather than raw mode, and the control character for EOF can be changed in the tty.

A perfectly workable solution to read n bytes (where n is a number) would be dd count=1 bs=n

Note that if you are typing multiple lines from a keyboard or there is a pause before all the data is sent, dd will interpret this as a block boundary. Adding iflag=fullbock will force dd to wait for the full 10 bytes before ending the block.

user10489
  • 6,740
  • 2
    Except that if you try e.g. dd count=1 bs=10 with input from the terminal, and type foo<newline>, it only copies four bytes. Or if you do something like (echo foo; sleep .1; echo abcdefghijklmn) |dd count=1 bs=10 it again copies only four bytes. – ilkkachu Dec 26 '21 at 17:01
  • It is probably reading that as a block. You could try reversing it with dd bs=1 count=10 – user10489 Dec 26 '21 at 21:04
  • Added a fix to the answer for partial blocks. – user10489 Dec 26 '21 at 21:42