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

发布于 2024-08-13 04:27:38 字数 1906 浏览 11 评论 0原文

当递归地浏览目录时,我在 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 表现得像它应该的那样?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绻影浮沉 2024-08-20 04:27:38

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

ksh93 常见问题解答在第三部分(Shell 脚本)中指出:

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

A18。在 ksh88 中这些是相同的。
然而,POSIX 标准选择
foo() 用于函数和定义的系统
V Release 2 的语义,以便
没有局部变量,所以
陷阱没有范围。克什93
保留 ksh88 语义
函数定义为函数名称,
并改变了 name() 语义
以匹配 POSIX 语义。清楚地,
函数名称更有用。

我无法访问 ksh93 shell 来测试这一点,但这意味着当您从其内部调用 rdir 函数时,变量 dir 会被覆盖。因此,基于上述内容,尝试将您的函数声明为 function rdir 以获取具有本地作用域变量的 ksh88 语义。

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.

与风相奔跑 2024-08-20 04:27:38

完美的!

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

做这个工作。谢谢。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文