运行脚本以列出子文件夹后,正在为空目录打印星号

sph*_*nix 7 shell-script

我试图编写一个 shell 脚本,它将目录路径 d 作为参数并递归打印 d 中所有文件和目录的深度缩进列表。然而,参数 d 是可选的,如果没有给出参数,所有文件和目录的深度缩进列表??在??这??当前的?? 目录?将要??被打印。这是我的代码:

# the method for tree

myspace=""
spaceCount=0
tree(){     
  cd "$1"
  for i in *; do
    if [ -d "$i" ]; then
      echo -n "|"   
      for (( j=0;j<spaceCount;j++ )) 
      do 
        echo -n "$myspace"  
      done
      echo "--$i"
      spaceCount=$((spaceCount+1)) 
      myspace="  |"
      tree "$i"
    else
      echo -n "|"
      for (( j=0;j<spaceCount;j++ )) 
      do 
        echo -n "$myspace"  
      done
      echo "--$i"
    fi
  done
  cd ../
  spaceCount=$((spaceCount-1))
}


if [ "$1" != "" ]; then
  file="$1"
fi
echo ".$file"
tree "$file"
Run Code Online (Sandbox Code Playgroud)

但是当一个文件夹为空时,它会打印一个像这样的星星:在此处输入图片说明

我该如何解决问题?

Sté*_*las 11

bash和 Bourne 类似的 shell 中(zsh例外),像*这样的glob不匹配任何文件扩展到自己(您的脚本使用ksh93语法,也被bashand识别zsh,尽管zsh默认情况下,对于不匹配的 glob ,您会收到致命错误) .

echo *在不包含文件(或仅包含隐藏文件)的目录中输出*.

在这里for i in *,使用for i in *(N)( zsh) 或for i in ~(N)*( ksh93)代替,或者如果使用bash,则设置nullglob选项(with shopt -s nullglob),以便不匹配的 glob 扩展不执行任何操作。

或者,您可以[ -e "$i" ] || continue在开头或for循环中添加 a以*通过检查文件是否存在来过滤掉(会影响您已阅读的目录的行为,但不会影响其搜索权限¹)。

更多阅读为什么 nullglob 不是默认值?


¹ 在这些目录中,*将扩展到所有非隐藏文件,但[ -e "$i" ]会为每个人返回 false,因为stat()系统调用将返回权限被拒绝