Infinite while-loop in BASH script

橙三吉。 提交于 2019-12-13 04:47:32

问题


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:


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.


回答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.




回答2:


You wrote you want to perform "count" on all dir's. 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, sometihing like

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



回答3:


If you really must avoid recursion, try this, 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 dir is empty, this shows an entry named "*"
      do
         test -e "$entry" || continue   # skip the entry "*" of an empty dir
         count "$entry"
         test -d "$entry" || continue
         todo+=("$entry")
      done
   done
done

However, please tell me - why can't you use recursion? It is a kind of allergy? A vow? Are there any local laws against recursive software where you live?




回答4:


I have no idea if this will work but its an intersting question I couldn't stop thinking about. Good luck

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


来源:https://stackoverflow.com/questions/27730620/infinite-while-loop-in-bash-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!