在ksh93中使用递归时的奇怪行为

时间:2009-11-30 19:41:54

标签: ksh pdksh

在递归浏览目录时,我在ksh93中遇到了一些问题。

创建一些文件和目录。

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

现在用ksh93脚本完成它。

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

将在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

使用pdksh / bash时会创建此

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

有人知道解决方法吗?或者是否存在使ksh93表现得如此的开关?

2 个答案:

答案 0 :(得分:3)

我对此有了一个想法 - 并且有正确的想法,但错误的原因。 pdksh遵循ksh88语义,快速谷歌揭示了在定义函数时ksh88和ksh93之间存在差异。

第三部分(Shell Scripting)中的

This FAQ for ksh93个州:

  

Q18。函数名和name()有什么区别?

     

A18。在ksh88中,这些是相同的。   但是,POSIX标准选择   foo()用于函数和已定义的System   V Release 2语义给他们这样做   没有局部变量等等   陷阱没有作用域。 ksh93的   保持ksh88的语义   函数定义为函数名,   并更改了name()语义   匹配POSIX语义。显然,   函数名称更有用。

我没有访问ksh93 shell来测试它,但暗示当你从内部调用rdir函数时,变量dir会被覆盖。因此,基于上述内容,尝试将函数声明为function rdir以获取具有本地范围变量的ksh88语义。

答案 1 :(得分:1)

完美!

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

完成这项工作。谢谢。