1

The purpose of my script is to count how many lines there are in a file. I know I could use wc for example but the purpose of this exercise is to understand processes and pipelines in Linux.

The script executed on my terminal:

C=0; cat file | while read line ; do C=$[ $C + 1 ] ; done ; echo $C

I always get 0 or whatever number I inizialize C variable.

In my textbook they explain this behavior saying that for every pipeline a new child process is created, it inherits all father variables but when the child dies the father still "see" his old values. And I'm ok with that.

What I don't understand is that I only see one pipeline, between C=0; cat file and while read line ; do C=$[ $C + 1 ] ; done ; echo $C. So I'm guessing that the second part is executed by the child (echo too) so why it prints the wrong value? Shouldn't the child increase C variable AND print the correct value as it belongs to the same pipe?

  • As a side note, shell variables should be lower-case. Environment variables should be upper-case. – ctrl-alt-delor Mar 24 at 19:25
2

What I don't understand is that I only see one pipeline, between C=0; cat file and while read line ; do C=$[ $C + 1 ] ; done ; echo $C.

No, that's not how it parses. You actually have three "pipelines":

C=0
cat file | while read line ; do C=$[ $C + 1 ] ; done
echo $C 

(Granted, the first and the third are degenerate single-command pipelines, but technically they still are just that. A pipeline is a sequence of one or more commands separated by the control operator '|')

In other words, the first and last semicolons separate pipelines. The ones between while and done don't, since they're a part of the while compound command.

A simpler example without any compound commands:

$ echo hello | tr a-z x ; echo you | tr a-z y
xxxxx
yyy

Here, we can easily see that only hello goes to the first tr, and only you goes to the second tr, i.e. the semicolon separates the pipelines.

The question Why is my variable local in one 'while read' loop, but not in another seemingly similar loop? contains a number of ways of doing what you tried to do, to be able to output the value of C as updated by the loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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