if/else 块的 else 部分永远不会在 Bash 脚本中运行



在下面的函数中,如果目录中有任何文件,我正在尝试打印文件名,如果没有,则打印错误,但内部 if/else 块的 else 部分,打印错误消息,永远不会运行。

这应该是合乎逻辑的,但我无法弄清楚。

walk_dir () {
shopt -s nullglob dotglob
for pathname in "$1"/*; do
if [ -d "$pathname" ]; then 
printf "nFiles under $(basename "$pathname")n";
printf "==========================================n";
walk_dir "$pathname";
else 
fc=$(find "$pathname" -maxdepth 1 -type f | wc -l);
# Here is the problem
if [ $fc -gt 0 ] && [ ! -z $fc ]; then 
printf '%sn' $(basename "$pathname");
else 
printf 'e[30mNo candidate file found.e[39mn';
fi
fi
done
}

walk_dir有 3 种情况

  • 非空文件夹
  • 空文件夹
  • 常规文件
  • 忽略特殊文件,这里可能不适用。

当为非空文件夹调用时,walk_dir 将在任何子文件夹(第 #7 行(上生成(递归(,然后在第 #12 行打印每个常规文件的基本名称。

当使用空文件夹调用时,walk_dir不会执行任何操作,因为"$1"/* 扩展到空列表。

当目录包含文件时,代码将"计算"第 #9 行中的文件数。这 l 只处理非目录 - 可能是文件(假设不是特殊设备等(。在这种情况下,它将对文件夹中的每个条目进行递归调用。

如果文件夹中有常规文件,代码将在第 #8 行执行find。在常规文件中将始终设置 fc="1",因此第 11 行的条件将始终为真,永远不会进入第 #13 行的 else 部分。

1  walk_dir () {
2      shopt -s nullglob dotglob
3      for pathname in "$1"/*; do
4          if [ -d "$pathname" ]; then 
5            printf "nFiles under $(basename "$pathname")n";
6            printf "==========================================n";
7            walk_dir "$pathname";
8          else 
9            fc=$(find "$pathname" -maxdepth 1 -type f | wc -l);
10            # Here is the problem
11            if [ $fc -gt 0 ] && [ ! -z $fc ]; then 
12              printf '%sn' $(basename "$pathname");
13            else 
14              printf 'e[30mNo candidate file found.e[39mn';
15            fi
16          fi
17      done
18   }

根据 @dash-o 的解释,我在迭代文件之前放置了 if 条件,它按预期工作。

walk_dir () {
shopt -s nullglob dotglob
fc=$(find "$1" -maxdepth 1 -type f | wc -l);
if [ $fc -eq 0 ] || [ -z $fc ]; then 
printf 'e[30mNo candidate file found.e[0mn';  
fi
for pathname in "$1"/*; do
if [ -d "$pathname" ]; then 
printf "nFiles under $(basename "$pathname")n";
printf "==========================================n";
walk_dir "$pathname";
else 
printf '%sn' $(basename "$pathname");
fi
done
}

太长了,无法发表评论!

我不明白的用法

fc=$(find "$pathname" -maxdepth 1 -type f | wc -l);

在代码的那部分$pathname要么是文件(不是目录(,要么是 for 循环的搜索模式(如果未找到文件(。所以这段代码看起来更好:

if [[ -f $filename ]]
then
# use input redirection to suppress filename
fc=$(wc -l <"$filename")
else
echo "not a plain file"
fi

最新更新