0

I have that sample script:

#!/bin/sh
while read ll </dev/fd/4; do
     echo "1 "$ll

     while read line; do
          echo $line
          read   input </dev/fd/3
          echo "$input"
     done 3<&0 <notify-finished

done 4<output_file

Currently The first loop do not iterate just stays on line 1. How do I fix that without bashisms because it has to be highly portable. Thanks.

3
  • 1
    /dev/fd is either a Linuxism or a bashism (bash emulates it on non-Linux operating systems, but not all shells do), so you're already nonportable. Use <&4, not </dev/fd/4. Commented Sep 30, 2016 at 14:46
  • Please extend your code to be a MCVE -- creating output_file and notify-finished, so it will run in a way that successfully demonstrates your bug without the person who wants to see your problem needing to do anything else. Commented Sep 30, 2016 at 14:48
  • @CharlesDuffy It turned out it was the </dev/fd/4 notation that was causing the trouble. If you second that comment as an answer, I'll accept it. Thank you. Commented Sep 30, 2016 at 14:55

1 Answer 1

3

Your code already has bashisms. Here, I'm taking them out (and simplifying the FD handling for better readability):

#!/bin/sh
while read ll <&4; do            # read from output_file
     printf '%s\n' "1 $ll"

     while read line <&3; do     # read from notify-finished
          printf '%s\n' "$line"
          read input             # read from stdin
          printf '%s\n' "$input"
     done 3<notify-finished

done 4<output_file

Run the script as follows:

echo "output_file" >output_file
echo "notify-finished" >notify-finished
echo "stdout" | ./yourscript

...and it correctly exits with the following output:

1 output_file
notify-finished
stdout

Notes:

  • echo's behavior is wildly nonportable across POSIX platforms. See the APPLICATION USAGE section of the POSIX spec for echo, which advises using printf instead.
  • /dev/fd/## is not specified by POSIX; it is an extension made available both by Linux distributions (creating a symlink to /proc/self/fd -- /proc being itself an unspecified extension) and by bash itself. Use <&4 in place of </dev/fd/4.
  • You probably want to use the -r argument to read -- which is POSIX-specified, and prevents the default behavior of treating backslashes as escape sequences for newlines and characters in IFS. Without it, foo\bar is read as foobar, thus not reading your data as it truly exists in its input sources.
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.