将Bash中使用测试运算符的if elif fi语句转换为case esac语句时遇语法错误求助
Bash中使用测试运算符的if elif fi语句转换为case esac语句时遇语法错误求助
嘿,我来帮你排查这个问题!你现在的case写法完全搞错了Bash里case语句的核心逻辑——它不是用来直接放[[ ... ]]这种条件表达式的,而是匹配某个变量的取值来执行对应分支的,和if elif的逻辑不一样哦。
错误原因分析
你用case true in然后把[[ ... ]]直接写在分支里,这不符合case的语法规则。case的标准结构是做模式匹配,而非直接执行条件判断,所以这种写法肯定会触发语法错误。
正确的转换方案
我们可以先把每个条件的判断结果映射成一个字符串标识,再用case匹配这个标识来处理分支,这样既符合case的语法,又能实现和原来if elif完全一致的逻辑:
for file in $(find "$1" -maxdepth 10000 -xdev -ignore_readdir_race); do # 先逐个判断,给当前文件的类型/状态一个标识值 if [[ "$file" =~ ^($OP0|$OP1|$OP2|$OP3|$OP4|$OP5|$OP6|$OP7|$OP8|$OP9)$ ]]; then file_type="skip_match" elif [[ ! -e "$file" ]]; then file_type="stale_file" elif [[ ! -s "$file" ]]; then file_type="zero_size" elif [[ -d "$file" ]]; then file_type="directory" elif [[ -h "$file" ]]; then # -h 和 -L 功能完全一致,无需重复判断 file_type="symlink" elif [[ -c "$file" ]]; then file_type="char_device" elif [[ -b "$file" ]]; then file_type="block_device" elif [[ -p "$file" ]]; then file_type="pipe" elif [[ -S "$file" ]]; then file_type="socket" elif [[ -f "$file" && -s "$file" ]]; then file_type="regular_file" else file_type="other_skip" fi # 用case匹配标识值,执行对应计数操作 case "$file_type" in skip_match) (( SkipCnt++ )) ;; stale_file) (( StalCnt++ )) ;; zero_size) (( ZeroCnt++ )) ;; directory) (( DirCnt++ )) ;; symlink) (( LinkCnt++ )) ;; char_device) (( CdevCnt++ )) ;; block_device) (( BdevCnt++ )) ;; pipe) (( PipeCnt++ )) ;; socket) (( SockCnt++ )) ;; regular_file) tar -cS --no-recursion --warning=none "$file" &>/dev/null (( FileCnt++ )) ;; other_skip) (( SkipCnt++ )) ;; esac done
额外小提示
- 给
find的参数$1加上双引号"$1",避免路径中包含空格或特殊字符时出现异常 -h和-L都是判断符号链接的,保留一个就够了,减少冗余判断- 所有涉及文件名的变量都要加双引号(比如
"$file"),防止文件名含空格、通配符等特殊字符导致错误
备注:内容来源于stack exchange,提问作者PyNewbie
相关产品推荐
相关产品推荐

