递归列出Bash中给定目录中的文件

Tom*_*rez 5 linux bash shell

我知道它可以使用ls -R path.但我正在尝试学习shell语言的语法和控制结构,所以我正在尝试编写自己的代码:

#!/bin/sh

arg=$1;

lsRec() {
    for x in $1*; do
        if [ -d "$x" ]; then
            lsRec $x;
        else
            echo "$x";
        fi
    done
}

lsRec $arg;
Run Code Online (Sandbox Code Playgroud)

当我调用命令时./ej2.sh ~/Documents/,终端抛出:segmentation fault (core dumped).为什么我收到此错误?我在代码中遗漏了什么?

谢谢.

mik*_*dld 8

您的算法进入无限循环,因为lsRec函数隐式期望其参数以"/"结尾.第一级工作,因为您传递以"/"结尾的路径作为输入,但第二级不工作,因为您正在进行递归调用的路径不以"/"结尾.你可以做的是在你进行递归调用时添加斜杠,所以它看起来像lsRec $x/,或者(更好的是)在循环参数中添加斜杠,因为for x in $1/*; do(因为系统通常会忽略多个相邻的路径分隔符).

展望未来,我建议你引用值(例如for x in "$1/"*,lsRec "$x",lsRec "$arg"),以避免出现问题时路径包含空格字符.当您在扫描目录层次结构下的名称中创建一个包含空格的目录时,您将到达那里.


arc*_*xus 5

这里的问题是“for x in $1*”找到了 $1,如果这有意义的话?所以它变成了一个无限循环。有两种解决方案:

  • 检查 x == $1
  • 将 for 循环更改为“for x in $1/*”

因为 $1 被传递给函数的参数替换了对吗?所以如果它发送“hello”,那么它就变成“for x in hello*”。现在,这是一个通配模式,将选择“你好”,因此是一个无限循环。

第二种解决方案有效,因为“hello”变成了“hello/*”而不是“hello*”。

这段代码对我来说很好用:

#!/bin/sh

arg=$1;

lsRec() {
    for x in "$1"/*; do
        echo "$x"
        if [ -d "$x" ]; then
            echo "This is a directory:"
            lsRec "$x";
        else
            echo "This is not a directory:"
            echo "$x";
       fi
    done
}

lsRec "$arg";
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!

  • 斜线还是不见了?:) (3认同)