tags:

views:

59

answers:

2

I'm facing some problems in ksh93, when going through directories recursively.

create some files and directories.

base=/tmp/nonsens

for i in {1..3}
do
    mkdir -p ${base}/dir${i}
    for j in {1..2}
    do
        mkdir ${base}/dir${i}/dir${j}
        touch ${base}/dir${i}/dir${j}/file${j}
        touch ${base}/dir${i}/file${j}
    done
done

Now going through it with a ksh93 script.

rdir ()
{
    typeset dir=$1

    for file in `ls $dir`
    do
        if [ -d $dir/$file ]
        then
            echo "Directory: $dir/$file"
            rdir $dir/$file
        else
            echo "File     : $dir/$file"
        fi
    done
}   

rdir /tmp/nonsens

will create this output in ksh93

cheko@chwiclu1:~> rdir /tmp/nonsens
Directory: /tmp/nonsens/dir1
Directory: /tmp/nonsens/dir1/dir1
File     : /tmp/nonsens/dir1/dir1/file1
File     : /tmp/nonsens/dir1/dir1/dir2
File     : /tmp/nonsens/dir1/dir1/file1
File     : /tmp/nonsens/dir1/dir1/file2
File     : /tmp/nonsens/dir1/dir1/dir2
File     : /tmp/nonsens/dir1/dir1/dir3

while using pdksh/bash will create this

cheko@redcube:~$ rdir /tmp/nonsens
Directory: /tmp/nonsens/dir1
Directory: /tmp/nonsens/dir1/dir1
File     : /tmp/nonsens/dir1/dir1/file1
Directory: /tmp/nonsens/dir1/dir2
File     : /tmp/nonsens/dir1/dir2/file2
File     : /tmp/nonsens/dir1/file1
File     : /tmp/nonsens/dir1/file2
Directory: /tmp/nonsens/dir2
Directory: /tmp/nonsens/dir2/dir1
File     : /tmp/nonsens/dir2/dir1/file1
Directory: /tmp/nonsens/dir2/dir2
File     : /tmp/nonsens/dir2/dir2/file2
File     : /tmp/nonsens/dir2/file1
File     : /tmp/nonsens/dir2/file2
Directory: /tmp/nonsens/dir3
Directory: /tmp/nonsens/dir3/dir1
File     : /tmp/nonsens/dir3/dir1/file1
Directory: /tmp/nonsens/dir3/dir2
File     : /tmp/nonsens/dir3/dir2/file2
File     : /tmp/nonsens/dir3/file1
File     : /tmp/nonsens/dir3/file2

Does someone know a workaround? Or does a switch exists that makes ksh93 behave as it should?

+1  A: 

I followed a thought on this -- and had the right idea but the wrong reason. pdksh follows ksh88 semantics, and a quick google reveals that there are differences between ksh88 and ksh93 when functions are defined.

This FAQ for ksh93 states in Part III (Shell Scripting):

Q18. What is the difference between function name and name()?

A18. In ksh88 these were the same. However, the POSIX standard choose foo() for functions and defined System V Release 2 semantics to them so that there are no local variables and so that traps are not scoped. ksh93 keeps the ksh88 semantics for functions defined as function name, and has changed the name() semantics to match the POSIX semantics. Clearly, function name is more useful.

I don't have access to a ksh93 shell to test this, but the implication is that when you call the rdir function from within itself, the variable dir is getting overwritten. So based on the above, try declaring your function as function rdir to get ksh88 semantics with locally scoped variables.

Chris J
A: 

perfect!

function rdir
{
    typeset dir=$1

    for file in `ls $dir`
    do
        if [ -d $dir/$file ]
        then
            echo "Directory: $dir/$file"
            rdir $dir/$file
        else
            echo "File     : $dir/$file"
        fi
    done
}

rdir /tmp/nonsens

does the job. Thank you.

cheko

related questions