1

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.

#!/bin/sh 

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

Actual output:

r
b
d
a
(etc)

Expected output:

r
Toby Speight
  • 8,678

2 Answers2

0

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.

cuonglm
  • 153,898
0

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

> exit | exit | echo wow
wow

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

cdosborn
  • 540