Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
834 views
in Technique[技术] by (71.8m points)

sh - Bourne shell: how should I terminate a script from within a while loop reading from a pipe?

Here is /bin/sh behaviour that surprised me, "exit" failing to exit:

$ cat sh_exit_from_while_pipe 
#!/bin/sh
echo foobar | while read blabla
do
    echo >&2 "Calling 'exit 2'"
    exit 2
    echo >&2 "It seems 'exit' did not terminate the while loop?"
done
echo >&2 "It seems 'exit' did not terminate the script?"

$ ./sh_exit_from_while_pipe 
Calling 'exit 2'
It seems 'exit' did not terminate the script?

Empirically I notice exit is leaving the while loop, but not the whole script. So my best guess at the moment is that, maybe, the pipe forks a new shell as subprocess, and exit only terminates the subprocess?

What would be a good way to terminate properly? (I might rewrite this entirely to avoid the "echo foobar |" - which might avoid this problem, but I'm still interested in how this might be more directly addressed.)

question from:https://stackoverflow.com/questions/65846851/bourne-shell-how-should-i-terminate-a-script-from-within-a-while-loop-reading-f

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

At the point where you execute exit 2, you can't tell how many "levels" of shell need to exit. The best you can do is use the exit status of the loop to see if that level should exit as well. For example,

echo foobar | while read blabla; do
    x=$(foo)
    if [ "$x" = bar ]; then
       exit 0  # We're done with the loop, success
    elif [ "$x" = gulp ]; then
       exit 1  # We're done with the loop, failure
    else
       exit 2  # We're done with the script, abort!
    fi
done

case $? in
  2) printf 'Fatal error in loop, exiting
' >&2; exit 1 ;;
  *) printf 'Loop result %d, continuing
' ;;
esac

printf 'Continuing script...'
  

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...