question about conditional test

question about conditional test

am 27.11.2007 20:30:33 von EdStevens

Platform: HP-UX 11 on Itanium

Given the following test script:

#!/bin/sh
toss()
{

# for each file from the 'find' - here cat is reading the pipe
for FPATH in `cat`
do
FILE=`basename $FPATH`
echo '==============='
echo FPATH: $FPATH
echo FILE: $FILE
case $FILE in
lost+found|cntrldptn.dbf)
;;
*)
echo "$FILE \c" >> $LOG 2>&1
if [ -d "$FILE" ]
then
echo " is a directory"
else
echo " is a file"
fi
;;
esac
done
}

# -- snip a bunch of code that eventually leads to this:

find . -print 2>&1 | toss
exit
#================ end code sample ================

And given that the 'find' returns something like this:

../dir1
../dir1/sub1
../dir1/sub1/sub1a
../dir1/sub1/sub1a/myfile

Now, as the for-loop is processing each of those, we see . . .

===============
FPATH: ./dir1
FILE: dir1
dir1 is a directory
===============
FPATH: ./dir1/sub1
FILE: sub1
sub1 is a file
===============
FPATH: ./dir1/sub1/sub1a
FILE: sub1a
sub1a is a file
===============
FPATH: ./dir1/sub1/sub1a/myfile
FILE: myfile
myfile is a file


So my question is, why is the 'if' conditional returning sub1 and
sub1a as a file instead of a directory?

Re: question about conditional test

am 27.11.2007 20:51:42 von OldSchool

On Nov 27, 2:30 pm, EdStevens wrote:
> Platform: HP-UX 11 on Itanium
>
> Given the following test script:
>
> #!/bin/sh
> toss()
> {
>
> # for each file from the 'find' - here cat is reading the pipe
> for FPATH in `cat`
> do
> FILE=`basename $FPATH`
> echo '==============='
> echo FPATH: $FPATH
> echo FILE: $FILE
> case $FILE in
> lost+found|cntrldptn.dbf)
> ;;
> *)
> echo "$FILE \c" >> $LOG 2>&1
> if [ -d "$FILE" ]
> then
> echo " is a directory"
> else
> echo " is a file"
> fi
> ;;
> esac
> done
>
> }
>
> # -- snip a bunch of code that eventually leads to this:
>
> find . -print 2>&1 | toss
> exit
> #================ end code sample ================
>
> And given that the 'find' returns something like this:
>
> ./dir1
> ./dir1/sub1
> ./dir1/sub1/sub1a
> ./dir1/sub1/sub1a/myfile
>
> Now, as the for-loop is processing each of those, we see . . .
>
> ===============
> FPATH: ./dir1
> FILE: dir1
> dir1 is a directory
> ===============
> FPATH: ./dir1/sub1
> FILE: sub1
> sub1 is a file
> ===============
> FPATH: ./dir1/sub1/sub1a
> FILE: sub1a
> sub1a is a file
> ===============
> FPATH: ./dir1/sub1/sub1a/myfile
> FILE: myfile
> myfile is a file
>
> So my question is, why is the 'if' conditional returning sub1 and
> sub1a as a file instead of a directory?


if i'm reading correctly, FILE is the basename (ie w/o full path), so
when you test
for $FILE being a directory, it is only looking in the current working
directory. Since is most likely isn't there, the if test fails and
you get the else clause.

your test needs to look at $FPATH instead....

Re: question about conditional test

am 27.11.2007 22:06:36 von EdStevens

On Nov 27, 1:51 pm, OldSchool wrote:
> On Nov 27, 2:30 pm, EdStevens wrote:
>
>
>
> > Platform: HP-UX 11 on Itanium
>
> > Given the following test script:
>
> > #!/bin/sh
> > toss()
> > {
>
> > # for each file from the 'find' - here cat is reading the pipe
> > for FPATH in `cat`
> > do
> > FILE=`basename $FPATH`
> > echo '==============='
> > echo FPATH: $FPATH
> > echo FILE: $FILE
> > case $FILE in
> > lost+found|cntrldptn.dbf)
> > ;;
> > *)
> > echo "$FILE \c" >> $LOG 2>&1
> > if [ -d "$FILE" ]
> > then
> > echo " is a directory"
> > else
> > echo " is a file"
> > fi
> > ;;
> > esac
> > done
>
> > }
>
> > # -- snip a bunch of code that eventually leads to this:
>
> > find . -print 2>&1 | toss
> > exit
> > #================ end code sample ================
>
> > And given that the 'find' returns something like this:
>
> > ./dir1
> > ./dir1/sub1
> > ./dir1/sub1/sub1a
> > ./dir1/sub1/sub1a/myfile
>
> > Now, as the for-loop is processing each of those, we see . . .
>
> > ===============
> > FPATH: ./dir1
> > FILE: dir1
> > dir1 is a directory
> > ===============
> > FPATH: ./dir1/sub1
> > FILE: sub1
> > sub1 is a file
> > ===============
> > FPATH: ./dir1/sub1/sub1a
> > FILE: sub1a
> > sub1a is a file
> > ===============
> > FPATH: ./dir1/sub1/sub1a/myfile
> > FILE: myfile
> > myfile is a file
>
> > So my question is, why is the 'if' conditional returning sub1 and
> > sub1a as a file instead of a directory?
>
> if i'm reading correctly, FILE is the basename (ie w/o full path), so
> when you test
> for $FILE being a directory, it is only looking in the current working
> directory. Since is most likely isn't there, the if test fails and
> you get the else clause.
>
> your test needs to look at $FPATH instead....

You are reading correctly, and that was the issue. Theory confirmed
by changing the
if [ -d "$FILE" ]
to
if [ -e "$FILE" ]
and observing the resulting behavior.

Thanks for the assist.

Re: question about conditional test

am 27.11.2007 22:13:14 von OldSchool

On Nov 27, 4:06 pm, EdStevens wrote:
> On Nov 27, 1:51 pm, OldSchool wrote:
>
>
>
>
>
> > On Nov 27, 2:30 pm, EdStevens wrote:
>
> > > Platform: HP-UX 11 on Itanium
>
> > > Given the following test script:
>
> > > #!/bin/sh
> > > toss()
> > > {
>
> > > # for each file from the 'find' - here cat is reading the pipe
> > > for FPATH in `cat`
> > > do
> > > FILE=`basename $FPATH`
> > > echo '==============='
> > > echo FPATH: $FPATH
> > > echo FILE: $FILE
> > > case $FILE in
> > > lost+found|cntrldptn.dbf)
> > > ;;
> > > *)
> > > echo "$FILE \c" >> $LOG 2>&1
> > > if [ -d "$FILE" ]
> > > then
> > > echo " is a directory"
> > > else
> > > echo " is a file"
> > > fi
> > > ;;
> > > esac
> > > done
>
> > > }
>
> > > # -- snip a bunch of code that eventually leads to this:
>
> > > find . -print 2>&1 | toss
> > > exit
> > > #================ end code sample ================
>
> > > And given that the 'find' returns something like this:
>
> > > ./dir1
> > > ./dir1/sub1
> > > ./dir1/sub1/sub1a
> > > ./dir1/sub1/sub1a/myfile
>
> > > Now, as the for-loop is processing each of those, we see . . .
>
> > > ===============
> > > FPATH: ./dir1
> > > FILE: dir1
> > > dir1 is a directory
> > > ===============
> > > FPATH: ./dir1/sub1
> > > FILE: sub1
> > > sub1 is a file
> > > ===============
> > > FPATH: ./dir1/sub1/sub1a
> > > FILE: sub1a
> > > sub1a is a file
> > > ===============
> > > FPATH: ./dir1/sub1/sub1a/myfile
> > > FILE: myfile
> > > myfile is a file
>
> > > So my question is, why is the 'if' conditional returning sub1 and
> > > sub1a as a file instead of a directory?
>
> > if i'm reading correctly, FILE is the basename (ie w/o full path), so
> > when you test
> > for $FILE being a directory, it is only looking in the current working
> > directory. Since is most likely isn't there, the if test fails and
> > you get the else clause.
>
> > your test needs to look at $FPATH instead....
>
> You are reading correctly, and that was the issue. Theory confirmed
> by changing the
> if [ -d "$FILE" ]
> to
> if [ -e "$FILE" ]
> and observing the resulting behavior.
>
> Thanks for the assist.- Hide quoted text -
>
> - Show quoted text -

np... so changing your original code to

if [ -d $FPATH ]
......


ought to give you the results you want....

Re: question about conditional test

am 28.11.2007 07:03:39 von Icarus Sparry

On Tue, 27 Nov 2007 13:13:14 -0800, OldSchool wrote:

> On Nov 27, 4:06 pm, EdStevens wrote:
>> On Nov 27, 1:51 pm, OldSchool wrote:
>> > On Nov 27, 2:30 pm, EdStevens wrote:
>>
>> > > Platform: HP-UX 11 on Itanium
>>
>> > > Given the following test script:
>>
>> > > #!/bin/sh
>> > > toss()
>> > > {
>>
>> > > # for each file from the 'find' - here cat is reading the pipe
>> > > for FPATH in `cat`
>> > > do
>> > > FILE=`basename $FPATH`
>> > > echo '==============='
>> > > echo FPATH: $FPATH
>> > > echo FILE: $FILE
>> > > case $FILE in
>> > > lost+found|cntrldptn.dbf)
>> > > ;;
>> > > *)
>> > > echo "$FILE \c" >> $LOG 2>&1
>> > > if [ -d "$FILE" ]
>> > > then
>> > > echo " is a directory"
>> > > else
>> > > echo " is a file"
>> > > fi
>> > > ;;
>> > > esac
>> > > done
>>
>> > > }
>>
>> > > # -- snip a bunch of code that eventually leads to this:
>>
>> > > find . -print 2>&1 | toss
>> > > exit
>> > > #================ end code sample ================
>>
>> > > And given that the 'find' returns something like this:

[snip]

>> > > So my question is, why is the 'if' conditional returning sub1 and
>> > > sub1a as a file instead of a directory?
>>
>> > if i'm reading correctly, FILE is the basename (ie w/o full path), so
>> > when you test
>> > for $FILE being a directory, it is only looking in the current
>> > working directory. Since is most likely isn't there, the if test
>> > fails and you get the else clause.
>>
>> > your test needs to look at $FPATH instead....

[snip]

>> Thanks for the assist.- Hide quoted text -
>>
>> - Show quoted text -
>
> np... so changing your original code to
>
> if [ -d $FPATH ]
> .....
>
>
> ought to give you the results you want....

It would also be considered better style to code "toss" as
toss()
{
while read FPATH
do
FILE=`basename $FPATH`
....
done

}

for a number of reasons. The main one is that using cat will use more
memory, and you will not do anything in the for loop until the cat has
finished, which will not be until the find has finished. The "while read"
approach will enable the find to work in parrallel with the find.

There are some improvements you can do over just using "read", which
are important if you are in an environment where the filenames are not
under your control. These involve using the "-r" switch to read, setting
the IFS variable, and using a more interesting way of specifing the
current directory to find. If your filenames are reasonable, then you
don't need to worry. The "while read" solution is as good as the for ..cat
approach.

Re: question about conditional test

am 28.11.2007 14:51:35 von EdStevens

On Nov 27, 3:13 pm, OldSchool wrote:
> On Nov 27, 4:06 pm, EdStevens wrote:
>
>
>
> > On Nov 27, 1:51 pm, OldSchool wrote:
>
> > > On Nov 27, 2:30 pm, EdStevens wrote:
>
> > > > Platform: HP-UX 11 on Itanium
>
> > > > Given the following test script:
>
> > > > #!/bin/sh
> > > > toss()
> > > > {
>
> > > > # for each file from the 'find' - here cat is reading the pipe
> > > > for FPATH in `cat`
> > > > do
> > > > FILE=`basename $FPATH`
> > > > echo '==============='
> > > > echo FPATH: $FPATH
> > > > echo FILE: $FILE
> > > > case $FILE in
> > > > lost+found|cntrldptn.dbf)
> > > > ;;
> > > > *)
> > > > echo "$FILE \c" >> $LOG 2>&1
> > > > if [ -d "$FILE" ]
> > > > then
> > > > echo " is a directory"
> > > > else
> > > > echo " is a file"
> > > > fi
> > > > ;;
> > > > esac
> > > > done
>
> > > > }
>
> > > > # -- snip a bunch of code that eventually leads to this:
>
> > > > find . -print 2>&1 | toss
> > > > exit
> > > > #================ end code sample ================
>
> > > > And given that the 'find' returns something like this:
>
> > > > ./dir1
> > > > ./dir1/sub1
> > > > ./dir1/sub1/sub1a
> > > > ./dir1/sub1/sub1a/myfile
>
> > > > Now, as the for-loop is processing each of those, we see . . .
>
> > > > ===============
> > > > FPATH: ./dir1
> > > > FILE: dir1
> > > > dir1 is a directory
> > > > ===============
> > > > FPATH: ./dir1/sub1
> > > > FILE: sub1
> > > > sub1 is a file
> > > > ===============
> > > > FPATH: ./dir1/sub1/sub1a
> > > > FILE: sub1a
> > > > sub1a is a file
> > > > ===============
> > > > FPATH: ./dir1/sub1/sub1a/myfile
> > > > FILE: myfile
> > > > myfile is a file
>
> > > > So my question is, why is the 'if' conditional returning sub1 and
> > > > sub1a as a file instead of a directory?
>
> > > if i'm reading correctly, FILE is the basename (ie w/o full path), so
> > > when you test
> > > for $FILE being a directory, it is only looking in the current working
> > > directory. Since is most likely isn't there, the if test fails and
> > > you get the else clause.
>
> > > your test needs to look at $FPATH instead....
>
> > You are reading correctly, and that was the issue. Theory confirmed
> > by changing the
> > if [ -d "$FILE" ]
> > to
> > if [ -e "$FILE" ]
> > and observing the resulting behavior.
>
> > Thanks for the assist.- Hide quoted text -
>
> > - Show quoted text -
>
> np... so changing your original code to
>
> if [ -d $FPATH ]
> .....
>
> ought to give you the results you want....

Yes, it does. Actually I tried the comparison of $FPATH first to
confirm it worked. Then used the -e test on $FILE to confirm the
theory of *why*.

Re: question about conditional test

am 28.11.2007 14:53:33 von EdStevens

On Nov 28, 12:03 am, Icarus Sparry wrote:
> On Tue, 27 Nov 2007 13:13:14 -0800, OldSchool wrote:
> > On Nov 27, 4:06 pm, EdStevens wrote:
> >> On Nov 27, 1:51 pm, OldSchool wrote:
> >> > On Nov 27, 2:30 pm, EdStevens wrote:
>
> >> > > Platform: HP-UX 11 on Itanium
>
> >> > > Given the following test script:
>
> >> > > #!/bin/sh
> >> > > toss()
> >> > > {
>
> >> > > # for each file from the 'find' - here cat is reading the pipe
> >> > > for FPATH in `cat`
> >> > > do
> >> > > FILE=`basename $FPATH`
> >> > > echo '==============='
> >> > > echo FPATH: $FPATH
> >> > > echo FILE: $FILE
> >> > > case $FILE in
> >> > > lost+found|cntrldptn.dbf)
> >> > > ;;
> >> > > *)
> >> > > echo "$FILE \c" >> $LOG 2>&1
> >> > > if [ -d "$FILE" ]
> >> > > then
> >> > > echo " is a directory"
> >> > > else
> >> > > echo " is a file"
> >> > > fi
> >> > > ;;
> >> > > esac
> >> > > done
>
> >> > > }
>
> >> > > # -- snip a bunch of code that eventually leads to this:
>
> >> > > find . -print 2>&1 | toss
> >> > > exit
> >> > > #================ end code sample ================
>
> >> > > And given that the 'find' returns something like this:
>
> [snip]
>
> >> > > So my question is, why is the 'if' conditional returning sub1 and
> >> > > sub1a as a file instead of a directory?
>
> >> > if i'm reading correctly, FILE is the basename (ie w/o full path), so
> >> > when you test
> >> > for $FILE being a directory, it is only looking in the current
> >> > working directory. Since is most likely isn't there, the if test
> >> > fails and you get the else clause.
>
> >> > your test needs to look at $FPATH instead....
>
> [snip]
>
> >> Thanks for the assist.- Hide quoted text -
>
> >> - Show quoted text -
>
> > np... so changing your original code to
>
> > if [ -d $FPATH ]
> > .....
>
> > ought to give you the results you want....
>
> It would also be considered better style to code "toss" as
> toss()
> {
> while read FPATH
> do
> FILE=`basename $FPATH`
> ....
> done
>
> }
>
> for a number of reasons. The main one is that using cat will use more
> memory, and you will not do anything in the for loop until the cat has
> finished, which will not be until the find has finished. The "while read"
> approach will enable the find to work in parrallel with the find.
>
> There are some improvements you can do over just using "read", which
> are important if you are in an environment where the filenames are not
> under your control. These involve using the "-r" switch to read, setting
> the IFS variable, and using a more interesting way of specifing the
> current directory to find. If your filenames are reasonable, then you
> don't need to worry. The "while read" solution is as good as the for ..cat
> approach.

And, as a side bonus, the READ is a bit more intuitive to read for
someone doing maintenance after the original author is gone! (Like
the situation I'm in now)

Thanks for the pointers.