help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: About using COPROC


From: Peng Yu
Subject: Re: About using COPROC
Date: Fri, 2 Apr 2021 17:41:12 -0500

On 4/2/21, Marco Ippolito <maroloccio@gmail.com> wrote:
>> By adding a longer sleep time, the following script works. But why the
>> coprocess is not halt to wait for its output to be taken? This
>> behavior is counterintuitive.
>
> Writes to stdout inside the coproc go into the kernel buffer for the pipe.
>
> Try this snippet to prove it to yourself, as you see.. the write to
> /tmp/urgent
> happens immediately:
>
>     coproc {
>         echo Hello, world
>         echo "NOW $$" > /tmp/urgent
>         sleep 5
>         echo Done
>     }
>     my_pid=$$
>     echo "Parent PID: $my_pid"
>     declare -p COPROC_PID
>     declare -p COPROC
>     cat /tmp/urgent
>     lsof -p "$my_pid" -a +E | grep FIFO
>     cat <&"${COPROC[0]}"
>
> You'll notice:
>
> * Writing "Hello, world" did not block
> * /tmp/urgent was written to immediately by the coproc
> * /tmp/urgent can be read immediately by the parent
> * Pipes are set by the kernel with matching fds
> * The first coproc write can be read by the parent as soon as it happens
> * The delayed coproc write is read by the parent after the sleep

I understand the nonblocking nature of coproc.

> Maybe you are thinking about named pipes, which block until the other side
> consumes the stream?

Here is what the manpage says. Since it is for communication between
the executing shell and the coprocess, I'd think that the shell is not
quick enough to take the output from the coprocess, the coprocess
should not just terminate so that the fd is not available for the
shell to read. Should this behavior be improved somehow?

"A coprocess is executed asynchronously in a subshell, as if the
command had been terminated with the & control operator, with a
two-way pipe established between the executing shell and the
coprocess."

Or people always have to put a `read dummy` to make sure the coproc
wait until something is written to it? Is this a reasonable
workaround?

coproc {
read dummy
seq 3
}

sleep 1
echo >&"${COPROC[1]}"
while IFS= read -r -u "${COPROC[0]}" line; do
        builtin printf '%s\n' "$line"
done

Also, I am trying the following coproc that takes input from stdin.
But it hangs. How to make it work? Thanks.

coproc {
awk -e '{ print 2 * $1 }'
}

sleep 1
seq 3 >&"${COPROC[1]}"
while IFS= read -r -u "${COPROC[0]}" line; do
        builtin printf '%s\n' "$line"
done

-- 
Regards,
Peng



reply via email to

[Prev in Thread] Current Thread [Next in Thread]