In a posix shell I would like to pass data to a background child process file descriptor and process output from the child in the parent.
No mkfifo please, just standard posix shell file descriptor duplication. No non-posix features like process substitions (<(cmd)
). No intermediate files. No /dev/fd or /dev/std{in,out,err} or /proc/pid.
Something like the following (which isn't working, so somewhere my concepts, and thus likely some of the comment annotations, are muddled):
child()
{
sed '1s|^|child: |;q' # prepend 'child: ' to first input line and quit
}
exec 4>&1 # open file descriptor 4 duplicated as stdout
# give the shell some time to start the child, then send data to child via fd 4
{ sleep 2; echo foo >&4; } &
out=$(child 4<&0) # connect fd 4 to stdin in child process
echo "out: $out"
I was hoping to see 'child: foo'
in out
. But instead I see foo
on stdout and child()
never terminates (so clearly the data is not going to the input file descriptor of the child).
Update: Adding a use case, per request.
In a loop, send data to a utility that reads stdin without having to re-spawn said utility each time through the loop. Having to re-fork/exec the utility every time through the loop is expensive. So... run utility as a background child process (exec just once) and send data from parent via the input file descriptor available to the child.
Update 2:
I guess I'm really trying to do what mkfifo does (create a in/out pair of fds where the output fd in the parent is connected to the input fd of the child, and the out fd of the child to the in fd of the parent), but without mkfifo being available (and if possible without temporary pipe files - i.e., just using anonymous file descriptors).
cmd | cmd
syntax). FWIW,exec 1>&4
will not work unless fd 4 is already opened, in which case it will make fd 1 (stdout) an alias of it (dup2(4, 1)
).coproc
command in various shells?while :; do echo yup; done | your_utility
. (yes, that does work; it may be thatyour_utility
is using buffered i/o). As to your "mkfifo or tempfiles without mkfifo or tempfiles", you're free to think I'm talking out of my ass; but if you really have a problem, better explain what you're trying to achieve exactly, maybe there are better ways to do it than the one you have latched onto.