This question already has an answer here:

I have the following script. It prints all of first characters to console from passwd, but my expectation was to get only one character and for the program to then terminate.


cat /etc/passwd |
while read -r line
    echo ${line} |
        grep -o . |
        while read char
            echo ${char}   
            exit 1       

Actual output:


Expected output:


marked as duplicate by Jeff Schaller, Archemar, Jakuje, garethTheRed, user79743 Mar 1 '16 at 19:40

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


Most Bourne-like shells, except zsh and ksh run each part of pipelines in subshells. Assuming you don't use zsh or ksh, then in your script, the last part of pipiline was run in subshell, so exit quit that subshell instead of current shell.

You will get the desire output in zsh or ksh.

Anyway, those code have many flaws:

If all you want is getting the first character in file:

dd bs=1 count=1 if=/etc/passwd 2>/dev/null

or with GNU dd:

dd status=none bs=1 count=1 if=/etc/passwd

It only works with ASCII characters. For multi-byte characters:

LC_ALL=en_US.utf8 awk '{print substr($0,1,1);exit}'

Change LC_ALL to what locale your text belong to.


Pipes creates sub-shells. The shell builtin exit terminates a shell. Resulting in the unexpected behavior in your case:

> exit | exit | echo wow

I suggest looking at the Pipelines section in man bash. Also look at help exit.

Not the answer you're looking for? Browse other questions tagged or ask your own question.