3

在递归浏览目录时,我在 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 行为正常的开关?

4

2 回答 2

3

我对此进行了思考 - 并且有正确的想法但错误的理由。pdksh 遵循 ksh88 语义,快速 google 发现在定义函数时 ksh88 和 ksh93 之间存在差异。

此关于 ksh93 的常见问题解答在第 III 部分(Shell 脚本)中说明:

问题 18。函数名和name()有什么区别?

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

我无权访问 ksh93 shell 来测试它,但这意味着当您从自身内部调用 rdir 函数时,该变量dir将被覆盖。因此,基于上述内容,尝试将您的函数声明为function rdir使用本地范围的变量获取 ksh88 语义。

于 2009-11-30T22:26:44.503 回答
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

做这项工作。谢谢你。

于 2009-11-30T22:40:40.680 回答