Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exit from BASH Infinite loop in a pipeline

Tags:

bash

shell

unix

I encountered a somewhat strange behavior of BASH infinite loops which outputs are pipelined to another processes. Namely, I run these two commands:

(while true; do echo xxx; done) | head -n 1
(while true; do date; done) | head -n 1

The first one exits instantly while the second one does not (and I assume it would run forever without being killed). I also tried an implicit infinite loop:

yes | head -n 1

and it also exits by itself. An appropriate line of output is immediately printed on the screen in each case. I am just curious what determines if such a commmand will finish.

like image 238
Tomasz Żuk Avatar asked Feb 12 '14 15:02

Tomasz Żuk


People also ask

How do you exit an infinite loop in bash?

Press Ctrl + Z to stop the job, and send it to the background.

How do you exit an infinite loop?

There is no way to stop an infinite loop. However, you can add a condition inside of the loop that causes it to break, or you can call the exit() function inside of the loop, which will terminate your program.

How do you exit a loop in bash?

In Bash scripting, a break statement helps provide control inside loop statements. Instead of waiting until the end condition, a break statement helps exit from a loop before the end condition happens.

How do you stop a loop in Linux?

break command is used to terminate the execution of for loop, while loop and until loop.


1 Answers

When head exits, the standard output of the parenthesized expression is closed. If an external command, like date, is used, the loop hangs. If an internal command of bash is used, like echo, the loop exits. For proof, use

(while true; do /bin/echo xxx; done) | head -n 1

and it will hang. If you use

(while true; do date; echo $? 1>&2; sleep 1; done) | head -n 1

you will see that on the second round, the date command returns an error exit code, i.e. something other but zero. Bash obviously does this not take as serious as when an internal command gets into problems. I wonder if this is intended or rather a bug in bash.

To make sure the loop is exited, this seems to work:

(set -e; while true; do date ; done) | head -n 1
like image 92
Harald Avatar answered Sep 20 '22 16:09

Harald