Redirecting stdin from fd 3-9?

Hi
I'm trying to do something on the bash command line that I will later put into a bash shell script.

I'm trying to take a program that reads stdin (using getline) and be able to keep it running in the background and fire "commands" to it. So what I thought I should do was to try taking stdin from (arbitrarily) file descriptor 4:

./myprogram <&4 &

Then later:
echo "inputstring" >&4
then later again
cat somefile >&4

This results is bash telling me "Bad file descriptor" when I start ./myprogram

The whole point of this is to exercise a library that I've written. Its wrapped in a C frontend that takes input from stdin (like a psuedo command line program). It's got to stay alive though so the data in my library under test can stay persistent.

Any idea if this is possible?

Use a FIFO.

Um, you can't use a file descriptor that does not exist (hopefully you have prepared your C code better :slight_smile:

As mentioned earlier, you should create a FIFO (a special file). Have a look at mknod's manual page (parameter p is what you are looking for).

pen

Actually, it can be done, but it's a bit ugly.

The problem is that when you run the job in the background, it's the background shell that creates fd4 and the parent (your command line shell) will know nothing about it. Because there's no one with fd4 opened for writing, the background job will immediately read EOF and terminate.

Something like this will give you a better shot:

exec >&4
./myprogram <&4 &
echo "message to program"

The first line redirects stdout to fd4 and leaves it turned on so that future data sent to stdout will go to fd4. (Writing an echo statement afterwards that goes to the real stdout is left as an exercise for the student. ;))

Now when you execute myprogram in the background, there will be a fd4 available so you won't get the error message, and fd4 will become stdin for that job.

Now when you print something to stdout it will go to the background job.

Using a FIFO (named pipe) will be similar. The important thing about named pipes is to open the reader first -- you'll get an error if you attempt to open the writer first (EPIPE on many system, "Attempt to write on a pipe with no readers").

If you have to stick with bash, then use one of the above techniques. But you're much better off (if possible) using a HERE document or the Korn shell's coprocess ability.