Discussion:
[Help-bash] How to not terminate a process using pipe?
Peng Yu
2018-02-11 23:28:05 UTC
Permalink
Hi,

In the following example, `cat` will be terminated when the first echo
runs. Is there a way to make `cat` persistent so that it can still
receive the input from the second echo?

$ cat main.sh
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:

set -v
mkfifo in out
cat < in > out &

echo x > in
read -r x < out
echo "$x"

echo y > in
read -r x < out
echo "$x"
--
Regards,
Peng
Pierre Gaston
2018-02-12 06:31:38 UTC
Permalink
Post by Peng Yu
Hi,
In the following example, `cat` will be terminated when the first echo
runs. Is there a way to make `cat` persistent so that it can still
receive the input from the second echo?
$ cat main.sh
#!/usr/bin/env bash
set -v
mkfifo in out
cat < in > out &
echo x > in
read -r x < out
echo "$x"
echo y > in
read -r x < out
echo "$x"
--
Regards,
Peng
I believe you will find several alternatives there:
http://mywiki.wooledge.org/BashFAQ/085
Peng Yu
2018-02-21 23:07:31 UTC
Permalink
The echo will open and close the the file refered to by in and out.
The close action will cause cat to quit.
What you need to do is to keep the files open, like
mkfifo in out
exec 111<in 222>out
echo x >&111
read -r x <&222
echo x >&111
read -r x <&222
# Close the file descriptors.
exec 111<&- 222<&-
This does not seem to work as it hangs there.

/tmp$ cat main1.sh
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:

tmpdir=$(mktemp -d)
mkfifo "$tmpdir"/infifo "$tmpdir"/outfifo
set -v
exec 111<"$tmpdir"/infifo 222>"$tmpdir"/outfifo

echo x >&111
read -r x <&222

echo x >&111
read -r x <&222

# Close the file descriptors.
exec 111<&- 222<&-

/tmp$ ./main1.sh
exec 111<"$tmpdir"/infifo 222>"$tmpdir"/outfifo
--
Regards,
Peng
Pierre Gaston
2018-02-22 07:00:47 UTC
Permalink
Post by Peng Yu
The echo will open and close the the file refered to by in and out.
The close action will cause cat to quit.
What you need to do is to keep the files open, like
mkfifo in out
exec 111<in 222>out
echo x >&111
read -r x <&222
echo x >&111
read -r x <&222
# Close the file descriptors.
exec 111<&- 222<&-
This does not seem to work as it hangs there.
/tmp$ cat main1.sh
#!/usr/bin/env bash
tmpdir=$(mktemp -d)
mkfifo "$tmpdir"/infifo "$tmpdir"/outfifo
set -v
exec 111<"$tmpdir"/infifo 222>"$tmpdir"/outfifo
echo x >&111
read -r x <&222
echo x >&111
read -r x <&222
# Close the file descriptors.
exec 111<&- 222<&-
/tmp$ ./main1.sh
exec 111<"$tmpdir"/infifo 222>"$tmpdir"/outfifo
--
Regards,
Peng
This script by itself does nothing, the pipe is blocking so you need at
least another process that reads and writes to these fifos.
For instance, this "works" with the kind of cat you had in your first
request (I added some echo to print something):


#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:
cat > in <out &

exec 111>in 222<out

echo x >&111
read -r x <&222
echo $x
echo x >&111
read -r x <&222
echo $x

# Close the file descriptors.
exec 111<&- 222<&-
Pierre Gaston
2018-02-22 08:09:20 UTC
Permalink
Post by Pierre Gaston
Post by Peng Yu
The echo will open and close the the file refered to by in and out.
The close action will cause cat to quit.
What you need to do is to keep the files open, like
mkfifo in out
exec 111<in 222>out
echo x >&111
read -r x <&222
echo x >&111
read -r x <&222
# Close the file descriptors.
exec 111<&- 222<&-
This does not seem to work as it hangs there.
/tmp$ cat main1.sh
#!/usr/bin/env bash
tmpdir=$(mktemp -d)
mkfifo "$tmpdir"/infifo "$tmpdir"/outfifo
set -v
exec 111<"$tmpdir"/infifo 222>"$tmpdir"/outfifo
echo x >&111
read -r x <&222
echo x >&111
read -r x <&222
# Close the file descriptors.
exec 111<&- 222<&-
/tmp$ ./main1.sh
exec 111<"$tmpdir"/infifo 222>"$tmpdir"/outfifo
--
Regards,
Peng
This script by itself does nothing, the pipe is blocking so you need at
least another process that reads and writes to these fifos.
For instance, this "works" with the kind of cat you had in your first
Sorry I messed up by copy/pasting bits and pieces in my previous example is
incorrect (wrong redirection directions for the cat process).
Hopefully this one is working:

#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:
rm -f in out
mkfifo in out

cat < in >out &


exec 111>in 222<out

echo foo >&111
read -r x <&222
echo x: $x

echo bar >&111
read -r x <&222
echo x: $x
exec 111<&- 222<&-

Loading...