if/else 块的 else 部分永远不会在 Bash 脚本中运行
else part of an if/else block never runs in Bash script
在下面的函数中,如果目录中有任何文件,我会尝试打印文件名,如果没有,则尝试打印错误,但内部 if/else 块的其他部分会打印错误消息,永远不会运行。
应该是合乎逻辑的,但我想不通。
walk_dir () {
shopt -s nullglob dotglob
for pathname in ""/*; 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 '%s\n' $(basename "$pathname");
else
printf '\e[30mNo candidate file found.\e[39m\n';
fi
fi
done
}
walk_dir有3个案例
- 非空文件夹
- 空文件夹
- 普通文件
- 忽略特殊文件,这里可能N/A。
当为非空文件夹调用时,walk_dir 将对任何子文件夹进行(递归)(第 7 行),然后在第 12 行打印每个常规文件的基本名称。
当使用空文件夹调用时,walk_dir 将不执行任何操作,因为“$1”/* 扩展为空列表。
当目录包含文件时,代码将 "count" 第 9 行中的文件数。这 l 只处理非目录 - 可能是文件(假设不是特殊设备等)。在这种情况下,它将对文件夹中的每个条目进行递归调用。
如果文件夹中有常规文件,代码将执行第 8 行的 find
。在常规文件上将始终设置 fc="1",因此第 11 行的条件将始终为真,永远不会进入第 13 行的 else 部分。
1 walk_dir () {
2 shopt -s nullglob dotglob
3 for pathname in ""/*; 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 '%s\n' $(basename "$pathname");
13 else
14 printf '\e[30mNo candidate file found.\e[39m\n';
15 fi
16 fi
17 done
18 }
根据@dash-o 的解释,我在遍历文件之前设置了 if 条件,结果如我所料。
walk_dir () {
shopt -s nullglob dotglob
fc=$(find "" -maxdepth 1 -type f | wc -l);
if [ $fc -eq 0 ] || [ -z $fc ]; then
printf '\e[30mNo candidate file found.\e[0m\n';
fi
for pathname in ""/*; do
if [ -d "$pathname" ]; then
printf "\nFiles under $(basename "$pathname")\n";
printf "==========================================\n";
walk_dir "$pathname";
else
printf '%s\n' $(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
在下面的函数中,如果目录中有任何文件,我会尝试打印文件名,如果没有,则尝试打印错误,但内部 if/else 块的其他部分会打印错误消息,永远不会运行。
应该是合乎逻辑的,但我想不通。
walk_dir () {
shopt -s nullglob dotglob
for pathname in ""/*; 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 '%s\n' $(basename "$pathname");
else
printf '\e[30mNo candidate file found.\e[39m\n';
fi
fi
done
}
walk_dir有3个案例
- 非空文件夹
- 空文件夹
- 普通文件
- 忽略特殊文件,这里可能N/A。
当为非空文件夹调用时,walk_dir 将对任何子文件夹进行(递归)(第 7 行),然后在第 12 行打印每个常规文件的基本名称。
当使用空文件夹调用时,walk_dir 将不执行任何操作,因为“$1”/* 扩展为空列表。
当目录包含文件时,代码将 "count" 第 9 行中的文件数。这 l 只处理非目录 - 可能是文件(假设不是特殊设备等)。在这种情况下,它将对文件夹中的每个条目进行递归调用。
如果文件夹中有常规文件,代码将执行第 8 行的 find
。在常规文件上将始终设置 fc="1",因此第 11 行的条件将始终为真,永远不会进入第 13 行的 else 部分。
1 walk_dir () {
2 shopt -s nullglob dotglob
3 for pathname in ""/*; 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 '%s\n' $(basename "$pathname");
13 else
14 printf '\e[30mNo candidate file found.\e[39m\n';
15 fi
16 fi
17 done
18 }
根据@dash-o 的解释,我在遍历文件之前设置了 if 条件,结果如我所料。
walk_dir () {
shopt -s nullglob dotglob
fc=$(find "" -maxdepth 1 -type f | wc -l);
if [ $fc -eq 0 ] || [ -z $fc ]; then
printf '\e[30mNo candidate file found.\e[0m\n';
fi
for pathname in ""/*; do
if [ -d "$pathname" ]; then
printf "\nFiles under $(basename "$pathname")\n";
printf "==========================================\n";
walk_dir "$pathname";
else
printf '%s\n' $(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