如何在bash / shell脚本中实现树命令?

时间:2018-03-01 15:42:43

标签: linux bash shell

我尝试在bash中实现一些代码,其输出类似于终端中的“tree”命令。

这是:

listContent() {
    local file
    for file in "$1"/*; do
        if [ -d $file ]; then
            countSpaces $file
            echo $?"Directory: $file"
            listContent "$file"
        elif [ -f $file ]; then
            countSpaces $file
            echo $?"File: $file"
        fi
    done
}

countSpaces() {
    local space="   "
    for (( i=0; i<${#$1}; i++ )); do
        if [ ${file:$i:1} = "/" ]; then
        space = space + space
        return space
    done
}

listContent "$1"

运行我提供的脚本:./ scriptName.sh directoryName 其中scriptName是我的脚本,directoryName是参数,它是代码应从中开始的目录的名称。

我希望看到这样的输出:

Directory: Bash/Test1Dir
    File: Bash/Test1Dir/Test1Doc.txt
Directory: Bash/Test2Dir
    Directory: Bash/Test2Dir/InsideTest2DirDir
        File: Bash/Test2Dir/insideTest2DirDoc.txt
File: Bash/test.sh

但是我在完成此代码时遇到了一些麻烦。有人可以帮我弄明白为什么它不起作用,我应该改变什么?

将不胜感激。

1 个答案:

答案 0 :(得分:1)

正确有效的实施可能如下所示:

listContent() {
  local dir=${1:-.} whitespacePrefix=$2 file
  for file in "$dir"/*; do
    [ -e "$file" ] || [ -L "$file" ] || continue
    if [ -d "$file" ]; then
      printf '%sDirectory %q\n' "$whitespacePrefix" "${file##*/}"
      listContent "$file" "${whitespacePrefix}    "
    else
      printf '%sFile %q\n' "$whitespacePrefix" "${file##*/}"
    fi
  done
}

注意:

  • 我们使用调用堆栈来跟踪每个递归调用附加的空白量,而不是计算空格。这样就无需计算每个名称中/的数量。
  • 我们引用所有参数扩展,除了在有限数量的上下文之一中,其中隐式避免了字符串拆分和glob扩展。
  • 我们避免尝试将$?用于跟踪数字退出状态的预期目的之外的其他任何内容。
  • 每当存在不受控制的数据(例如文件名)时,我们都会使用printf %q,以确保即使是恶意名称(包含换行符,光标控制字符等)也能明确打印出来。