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.