I'm not sure if this is a bug, or a feature but I had to debug some code as
a result so I'd like to bring it to your attention, and if you know of a
better way to read from pipes please let me know.

#!/bin/bash
numstr=${1}
rdlnk=$(readlink /proc/$$/fd/0)
function get_input() {
 ## echo "PID: $$, PPID: $PPID " && sleep 500
 ## What works is:
 ## if grep -Eq "^pipe:|deleted" <<< "${rdlnk}" && [[ "${rdlnk}" !=
"$(readlink /proc/$PPID/fd/0)" ]]; then
 if grep -Eq "^pipe:|deleted" <<< "${rdlnk}"; then
  while IFS= read -r piped_input || break; do
numstr="${numstr}${piped_input}"; done
 elif [[ -f "${rdlnk}" ]]; then
  numstr=$(head -1 "${rdlnk}")
 elif [[ -e "${numstr}" ]]; then
  numstr=$(head -1 "${numstr}")
 fi }

get_input
echo "the number string ${numstr} ..."
exit 0

I have fixed this problem as you can see in the comment in the code
itself, by looking at the parent process fd0.

Note: If you want to take a closer look at this, you may want to
uncomment the first line and take a look at ls -al
/proc/[PID|PPID]/fd/0.

To test this out, save the script above to a file /tmp/test.bsh.

$> for a in {1..5}; do /tmp/test.bsh "$a"; done
the number string 1 ...
the number string 2 ...
the number string 3 ...
the number string 4 ...
the number string 5 ...

$> while read a; do /tmp/test.bsh "$a"; done < <(seq 1 5)
the number string 12345 ...

If you swap commented conditionals you will see that both now work properly.

Is this supposed to happen? I don't see the point of writing the open pipe
to fd0 in the child process in this case.

Reply via email to