0

I'm really struggling to see why this while-loop never ends, when the loop starts, my variable LOC is set to Testing/, which is a directory I created to test this program, it has the following layout:

Layout of my Testing Directory

I want the loop to end once all Directories have had the "count" function applied to them.
Here are the things I have tried;

I've checked my count function, and it doesn't produce an infinite loop

I've tried running through the algorithm by hand

PARSE=1
LOC=$LOC/
count
AVAILABLEDIR=$(ls $LOC -AFl | sed "1 d" |  grep "/$" | awk '{ print $9 }')
while [ $PARSE = "1" ]
do

if [[ ${AVAILABLEDIR[@]} == '' ]]; then
    PARSE=0
fi

DIRBASE=$LOC

for a in ${AVAILABLEDIR[@]}; do
LOC="${DIRBASE}${a}"
LOCLIST="$LOCLIST $LOC"
count
done

for a in ${LOCLIST[@]}; do
TMPAVAILABLEDIR=$(ls $a -AFl | sed "1 d" |  grep "/$" | awk '{ print $9 }')
PREPEND=$a
if [[ ${TMPAVAILABLEDIR[@]} == '' ]]; then
    continue
fi

for a in ${TMPAVAILABLEDIR[@]}; do
    TMPAVAILABLEDIR2="$TMPAVAILABLEDIR2 ${PREPEND[@]}${a}"
done

NEWAVAILABLEDIR="$NEWAVAILABLEDIR $TMPAVAILABLEDIR2"
done

AVAILABLEDIR=$NEWAVAILABLEDIR
NEWAVAILABLEDIR=''
LOC=''
done

I am really struggling, and any input would be greatly appreciated, I've been trying to figure this out for the last couple of hours.

5
  • 1
    Never parse output from ls. What exactly you are trying to do? May be it must be much simpler? Commented Jan 1, 2015 at 12:07
  • I have to, I'm trying to count files, folders and folder sizes. except without using "find", "locate" or "du" or any sort of recursive function. Commented Jan 1, 2015 at 12:12
  • have a read this Commented Jan 1, 2015 at 12:15
  • 1
    Why do you reject recursive functions which do what you need? Commented Jan 1, 2015 at 12:16
  • Related: Why not upload images of code/errors when asking a question? (e.g., "Images should only be used to illustrate problems that can't be made clear in any other way, such as to provide screenshots of a user interface."). Commented Aug 18, 2022 at 19:20

4 Answers 4

1

You should try to run the script with argument -x, or write it into the first line:

#!/bin/bash -x

Then it tells you everything it does.

In that case, you might notice two errors:

  1. You never reset TMPAVAILABLEDIR2

  2. You do ls on regular files as well.

Sign up to request clarification or add additional context in comments.

1 Comment

I also noticed that I don't reset LOCLIST, but thank you for the inspiration to check whether I reset everything!
1

If you really must avoid recursion, try this. It completely recursion-free:

#!/bin/bash

count() {
   echo counting "$1"
}

todo=(Testing)

while test ${#todo[@]} != 0
do
   doit=("${todo[@]}")
   todo=()
   for dir in "${doit[@]}"
   do
      for entry in "$dir"/*   # If the directory is empty, this shows an entry named "*"
      do
         test -e "$entry" || continue   # Skip the entry "*" of an empty directory
         count "$entry"
         test -d "$entry" || continue
         todo+=("$entry")
      done
   done
done

5 Comments

it's uni work, I didn't expect people to rewrite the entire thing, and now that I see the full solution, it's really hard not to just use it, but that'd be plagiarism, sigh the moral dilemma
Rewriting is much less work then showing you line by line what's wrong.
@MeeranBala-Kumaran: Keep in mind that arrays are only available since Bash 3, I think. It's possible they aren't available on the machine your teacher will use. Just saying.
@HansKlünder I know, and I appreciate you doing this for me, thank you. I just really don't wanna copy someone elses' work and risk getting 0 in my coursework.. I've saved your solution as a last option, if I really can't fix mine, or come up with one that hasn't been given to me.
If your teacher does not have, eplace the array by a simpler and more error-prone string that contains directories separated by blanks. You use test -z "$todo" and a few similar changes.
1

You wrote you want to perform "count" on all directories. Look at the options of find:

find $LOC -type d | while read dir; do
   cd $LOC
   cd ${dir}
   count
done

Or shorter (when your function count accepts a directory as parameter 1):

find $LOC -type d | xargs count

I now see you do not want to use find or ls -R (recursive function). Then you should make your own recursive function, something like

function parseDir {
   ls -d */ $1 | while read dir; do
      count
      parseDir $1/$dir
   done
}

1 Comment

According to a comment find is not allowed. However, the OP should have written this in the actual question. This solution is what any future internaut will want, bar the find exception.
0

I have no idea if this will work, but it’s an interesting question I couldn't stop thinking about.

while true ; do
    for word in "$(echo *)" ; do
        if [[ -d "$word" ]] ; then
            d[$((i++))]="$PWD"/"$word"
        elif [[ -f "$word" ]] ;then
            f[$((j++))]="$PWD"/"$word"
        fi
    done

    [[ $k -gt $i ]] && cd ..
    cd "$d[$((k++))]" || break
done

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.