Function Recursion Shift Problem

Hi, I'm trying to create a script that will display the contents of the users directories, but i'm confused about how to incorporate the shift properly.

The problem I'm getting with my script is that it goes throught the first couple of directories but then returns an error as it loses the first directory when continuing the search to other directories (I hope that makes sense?!)
EDIT: I apologise, that was the old problem, now the problem is the path to be searched adds the wrong directories so it looks in paths that do not exist

Here's my code, any help would be greatly appreciated.

direc=~
list=$(ls -l $direc | egrep '^d' | cut -d" " -f8)
function printList() {
        for line in $*
        do
                echo $line
                list=$(ls -l $direc/$1 | egrep '^d' | cut -d" " -f8)
                direc=$direc/$1
                shift
                printList $list
 
        done
}
printList $list

EDIT2: I have also tried suppressing the error returned by the ls to dev null by editing the line inside the function:

                list=$(ls -l $direc/$1 | egrep '^d' | cut -d" " -f8 2>/dev/null)

and also

                list=$(ls -l $direc/$1 | egrep '^d' | cut -d" " -f8) 2>/dev/null

but niether work, both return the same output, in other words they are still not suppressesing the standard error. :frowning:

What's wrong with:

ls ~username

... or I'm missing something?

Could you post an example of the desired output?

I'm not quite sure what ls ~username would do, when I try it, it outputs the same as a normal ls command...

Basically what I want my script to do is display a visual representation of the specified directory and all its sub directories (like the tree command).

I have managed to supress the original ls error by adding the 2>/dev/null to the function call itself which seems to work ok now:

#!/bin/bash
direc=~
seperator=....
list=$(ls -l $direc | egrep '^d' | cut -d" " -f8)
function printList() {
        for line in $*
        do
                echo $line
                list=$(ls -l $direc/$1 | egrep '^d' | cut -d" " -f8 )
                direc=$direc/$1
                shift
                printList $list 2>/dev/null

        done
}
printList $list 2>/dev/null

But my script still does not work correctly, it will scan through the first directory found and display it along with all the subdirectories, but when it comes to loop back to the original directory and display the next directory it won't scan through and display the subdirectories of it. (I'm finding it quite hard to explain but I hope you can understand)

the output given will be something like: (where the . and number represent the directories and subdirectories)
direc1
direc1.1
direc1.1.1
direc1.1.2
direc1.2
direc1.2.1
direc2

and then it halts, where as i want it to display an output like:
direc1
direc1.1
direc1.1.1
direc1.1.2
direc1.2
direc1.2.1
direc2
direc2.1
direc2.1.1
direc2.2
direc2.2.1
direc3
direc3.1
direc3.1.1
direc3.2
direc4
...etc

I still cannot understand: given your example direc1.1, 1 is the name of the subdirectory or some sort of auto incremented id?
Do you want to produce an output similar to this one:

$ find -type d
.
./dir1
./dir1/dir11
./dir1/dir11/dir111
./dir1/dir12
./dir1/dir12/dir121
./dir2

Kind of... Simply put, what I would like to do is create a script which displays an output similar to the unix tree command

tree ~

but only list directories and subdirectories, no files.

I hope that is clearer. And I greatly appreciate your help and time. :slight_smile:

Did you try:

tree -d ~

or (as already stated):

find -type d

to better explain my direc1, direc1.1 blah blah...
direc1 would be the parent directory, direc1.1 and direc 1.2 would be sub directories of direc1, and direc1.1.1 would be a sub directory of the subdirectory direc1.1

i hope thats a bit clearer :confused:

ah yes

tree -d ~ 

is basically the output i require, but i need to make my own script to create this output (for a course I am on, to help me understand recursion better) but I'm having difficulty with the creation of this script, it's really giving me a headache.
From my code above, can you tell if I am close?!
Thanks for your help

With bash you can try something like this (modified version of a solution found on c.u.s.):

#!/bin/bash

prg=$0

shopt -s nullglob

printd () {

  local _d

  [[ -d "$1" && -e "$1" ]] || {
    printf 'usage: %s <path>\n' "$prg"
    return 1
    }

  cd "$1"

  for _d in "$PWD"/*/; do
    _d="${_d%/}"
    printf '%s|__%s/\n' "$_ind" "${_d##*/}"
    _ind="$_ind!  "
    [ -x "$_d" ] &&  printd "$_d"
    _ind="${_ind%???}"
  done

}

printd "$1

Or you can use something like this:

find . -type d | 
  sed 's;[^/]*/;|____;g;s;____|;    |;g'

awesome, thanks a lot man, I'm not understanding the code properly at the moment but will keep going through it until I understand it fully!

thanks for your help, Nuvpal

I've kind of figured this method out, but is there a way of doing it without changing to the directory?

I know I'm close with my script:

#!/bin/bash
direc=~
seperator=....
list=$(ls -l $direc | egrep '^d' | cut -d" " -f8)
count=0
function printList() {

        for line in $*
        do
                echo "$line -($count)"
                ((count++))
                nextList=$(ls -l $direc/$1 | egrep '^d' | cut -d" " -f8 )
                direc=$direc/$1
                shift
                printList $nextList 2>/dev/null
                echo -n $seperator
        done
}
printList $list 2>/dev/null

but is there a way of doing it like I've attempted? By listing the directory from home rather than changing to each directory?
cheers