0

Imagine I have the following program/script ./generate-infinite-byte-stream:

#!/bin/bash
echo -n 'hello'
sleep infinity

The infinite sleep command represents a network connection that may or may not deliver more data in the indefinite future that I am not interested in.

I would like to have a program, let's call it take 5 that runs ./generate-infinite-byte-stream until it has output 5 bytes on stdout and then terminates it:

take 5 ./generate-infinite-byte-stream
# gives 'hello' and returns with exit code 0

Is there such a program or do I need to roll my own with popen()? The program take should also redirect stdin to the executed program.

Note: head -c 5 does not do the right thing, because it does not terminate:

./generate-infinite-byte-stream | head -c 5
# this returns 'hello', but never terminates

Aside: The name Take is inspired by the https://reference.wolfram.com/language/ref/Take.html command which returns the first n elements of a list.

masterxilo
  • 117
  • 5
  • That script is very poorly named. If it really did produce more output, then it would be terminated by trying to write to a closed pipe. – Toby Speight Jun 04 '21 at 09:59
  • @TobySpeight You mean the `./generate-infinite-byte-stream` script? That's fine. You could even imagine that it said `echo hello; sleep 1; echo world; sleep infinity`. I do not care about the extra output after the first 5 bytes and I want to completely ignore any errors that might occur and terminate that program/script as soon as possible after the first 5 bytes have been returned, ignoring all the rest. – masterxilo Jun 04 '21 at 10:04
  • I don't know of a program that does what you want - it's usually sufficient to close the stream, meaning that the 6th byte of output will kill the producer with `SIGPIPE`. To terminate the producer immediately after byte 5, rather than at byte 6, will likely require a simple program. – Toby Speight Jun 04 '21 at 10:10

1 Answers1

1

If your shell is Bash, you could use a process substitution. Demo:

dd bs=1 count=5 < <(printf hello; sleep infinity)

That doesn't kill the producer, but does disconnect it so that the dd command completes. This may or may not be what you need.

Toby Speight
  • 8,460
  • 3
  • 26
  • 50
  • Thank you, that already helps as a starting point. But I will need a solution that kills the producer, otherwise the system will get littered with open network connections waiting for irrelevant data and lots of running processes. – masterxilo Jun 04 '21 at 10:27
  • Yes, then you'll need to write a small program to signal the writer when you've read enough. – Toby Speight Jun 04 '21 at 10:34