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.