Help Understanding While Loop

Eric F Crist ecrist at secure-computing.net
Sun Oct 16 11:11:23 PDT 2005


On Oct 15, 2005, at 5:59 PM, Drew Tomlinson wrote:

> On 10/14/2005 3:24 PM David Kirchner wrote:
>
>
>> On 10/14/05, Drew Tomlinson <drew at mykitchentable.net> wrote:
>>
>>
>>> OK, I've been working on an sh script and I'm almost there.  In the
>>> script, I created a 'while read' loop that is doing what I want.   
>>> Now I
>>> want to keep track of how many times the loop executes.  Thus I  
>>> included
>>> this line between the 'while read' and 'done' statements:
>>>
>>> count = $(( count + 1 ))
>>>
>>> I've tested this by adding an 'echo $count' statement in the loop  
>>> and it
>>> increments by one each time the loop runs.  However when I  
>>> attempt to
>>> call $count in an 'echo' statement after the 'done', the variable is
>>> null.  Thus I assume that $count is only local to the loop and I  
>>> have to
>>> export it to make it available outside the loop?  What must I do?
>>>
>>>
>>
>> Oh yeah, that's another side effect of using the while read method.
>> Because it's "| while read" it's starting a subshell, so any  
>> variables
>> are only going to exist there. You'd need to have some sort of 'echo'
>> within the while read, and then | wc -l at the end of the while loop,
>> or something along those lines.
>>
>> The IFS method someone else mentioned, in regards to 'for' loops,
>> would probably be better all around. So you'd want:
>>
>> OLDIFS=$IFS
>> # Note this is a single quote, return, single quote, no spaces
>> IFS='
>> '
>>
>> for i in `find etc`
>> do
>> done
>>
>> IFS=$OLDIFS
>>
>>
>
> OK, I've tried this and it does fix the "count" problem.  However  
> it messes up another part of the script and I'm trying understand  
> why.  I tried to make this script dynamic in that all I would need  
> to do is edit variables set at the top and then not have to worry  
> about all occurrences in the script.  Thus I set the following  
> variables:
>
> remote_pictures_dir="/multimedia/Pictures"
> local_pictures_dir="/tv/pictures"
> find_args="-iname '*.jpg' -or -iname '*.gif'"
>
> Then I called the 'find' command as follows:
>
> for original in $(/usr/bin/find $remote_pictures_dir $find_args - 
> print)
>
> But when I run my script, I get "/usr/bin/find: invalid predicate `- 
> iname '*.jpg' -or -iname '*.gif''".  However if I don't try and use  
> $find_args and type the arguments in specifically, the script runs  
> fine.  I tried various combinations of quoting and escaping those  
> quotes but can't come up with a combination that works.
>
> What is going on?  And is there some way to set verbosity so I can  
> see how the shell is expanding the variables?
>
> Thanks much,
>
> Drew

IIRC, you can do that be appending a '-x' after #!/bin/sh.  Your  
first line would look like this:

#!/bin/sh -x

This will result in the script echoing all of the commands as they're  
executed.

As far as the count problem, try declaring the variable before the  
while loop.  For example:

doit = 0
count = 0
while [ $doit -lt 4 ]
do
count=$[$count+1]
doit=$[$doit+1]
done
echo $count

HTH
_______________________________________________________
Eric F Crist                  "I am so smart, S.M.R.T!"
Secure Computing Networks              -Homer J Simpson



More information about the freebsd-questions mailing list