LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Bash script while loop problems (http://www.linuxquestions.org/questions/programming-9/bash-script-while-loop-problems-524757/)

whammack 02-01-2007 02:33 PM

Bash script while loop problems
 
I have a while loop in my script that doesn't work correctly. It is designed to read the lines from a file and concatanate them into one long string. It does this fine WITHIN the loop, but once outside the loop the concatinated variable is empty. What am I missing here? The section of code is

List=""
cat $InFile | while read line
do
List=$List" "$line
echo $List
done
echo "Here 1"
echo $List
echo "Here 2

Note that $List within the loop prints correct: It grows with each line read, but once outside the loop $List (just below echo "Here 1" is empty!

Xaphoid 02-01-2007 03:22 PM

Gee that looks like more work then needed!?
 
Couldn't you just do something simple like:

Code:

List=`cat FILENAME`
Note those are back quotes the one you get when you press ~ key on a US keyboard.

I think that will do it for you and in one line!

whammack 02-01-2007 04:36 PM

My, oh, my that's just dandy! Works fine. Still ... I wonder what was happened with my while loop .... Thanks for your prompt reply.

makyo 02-01-2007 06:53 PM

Hi, whammack.

I haven't looked at the internals of the shells, but this how it seems to work.

Constructs like while will be run in a separate process, so the variables will not be available to the outside process, even though they look like they will be or should be.

I put a monitor statement outside and inside your loop:
Code:

The outside process is:
  PID TTY          TIME CMD
 4894 pts/1    00:00:00 tcsh
18760 pts/1    00:00:00 sh
18762 pts/1    00:00:00 ps
 The loop process is:
  PID TTY          TIME CMD
 4894 pts/1    00:00:00 tcsh
18760 pts/1    00:00:00 sh
18764 pts/1    00:00:00 sh
18765 pts/1    00:00:00 ps

So process 18760 is the main shell process (ignore tcsh, I use that for interactive work), but as soon as you are in the loop, another shell process appears, 18764, to deal with the loop. You cannot pass contents of variables back up the process tree, so your original value is still there.

If it's critical that you save that, you would need to use some other method, such as writing it to a file. Note that just as you can pipe into a loop, you can re-direct out of the loop ... cheers, makyo

jlliagre 02-01-2007 07:22 PM

Here is one version that overcome the subprocess issue:

Code:

List=""
while read line
do
  List=$List" "$line
  echo $List
done < $InFile
echo "Here 1"
echo $List
echo "Here 2"

By the way, it's not the while that makes a separate process, but the pipe.

whammack 02-01-2007 07:26 PM

Thanks so much. Thought it was a separate process - but I often get confused by parent and child and so on -- these posts were very, very helpful.

spicetrader 02-01-2007 08:10 PM

Is $InFile from a Windows system? The CR/LF line ends on Windows may contribute to the issue. Working on my Cygwin-on-XP rig, I got a pile of collided text in $List, when reading from a CR/LF file. Then I gave command

cat readme.txt | d2u > ureadme.txt

and ran with InFile=ureadme.txt

which worked fine. I used zsh.

makyo 02-02-2007 05:31 AM

Hi.

A thank you to jlliagre for clarifying the issue (and jogging my memory about the items in a pipeline) ... cheers, makyo


All times are GMT -5. The time now is 07:09 PM.