Is it possible to do a non-blocking read in bash 3.2 that is also portable to POSIX environments?

In modern versions of bash it's possible using read -r -d'' -t $TIMEOUT -N $NBYTES myvar but I need to support bash 3.2, where -N doesn't exist and upon timeout myvar is not written to and the the data that was partially read is lost.

I have seen other answers that suggest using dd with a GNU-specific iflags argument but that won't work for me because I can't be sure that GNU dd will be present.

Since my goal is portability I would prefer not to write this in Python, Perl, etc., but that's what I'll have to do if this is impossible.

For context, what I want to do is to run script with its output redirected to a pipe. My bash script will read from the pipe and when any amount of data is available it'll wrap it in an envelope and output it. This will make it possible for the consumer to multiplex several streams of input. In order for it to perform well, it needs to be low-latency and also work on reasonable-size chunks of data (not 1 byte at a time).

  • 1
    what's your consumer? From a system designer's point of view, this sounds like you'd want the POSIX route and use the poll C library call to get "instantly" notified by any of a set of file descriptors having data ready. Reading in a blocking manner is not a proper way of multiplexing multiple streams into one! But this makes a lot of assumption on your system design, and I'm not quite sure where in your described system you have multiple streams, and where you blockingly want to read. May 7 at 21:26
  • C would be wonderful but my goal is to pass this whole thing as an argument to ssh, so it needs to be in a scripting language. I can't count on there being a C complier on the remote host, nor can I count on the filesystem being writable. I'm trying to give the terminal emulator I develop out-of-band signaling (e.g., to query the remote host for various bits of state like the list of running processes) for an ssh connection that it manages on the user's behalf.
    – George
    May 9 at 5:55
  • so the script you want to write is what you plan to pass to SSH as argument, correct? What specifically does it need to read? This is all very interesting, but now I'm a bit confused. I know this is asking much, but could you maybe make a sketch and add it as a picture to your question so that we understand the overall problem better? May 9 at 7:34
  • I wrote up a more detailed description of the idea here: gist.github.com/gnachman/21200f5f1647c7db43eb397d19910ee9
    – George
    May 12 at 2:43


Your Answer

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

Browse other questions tagged or ask your own question.