我有以下有效的代码:
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 (( SkipCnt++ )) # Count of skipped files
elif [[ ! -e "$file" ]] ; then (( StalCnt++ )) # Count of files that existed last run, but don't now
elif [[ ! -s "$file" ]] ; then (( ZeroCnt++ )) # Count of zero sized files
elif [[ -d "$file" ]] ; then (( DirCnt++ )) # Count of directories
elif [[ -h "$file" || -L "$file" ]] ; then (( LinkCnt++ )) # Count of symbolic links
elif [[ -c "$file" ]] ; then (( CdevCnt++ )) # Count of character devices
elif [[ -b "$file" ]] ; then (( BdevCnt++ )) # Count of block devices
elif [[ -p "$file" ]] ; then (( PipeCnt++ )) # Count of pipes
elif [[ -S "$file" ]] ; then (( SockCnt++ )) # Count of sockets
elif [[ -f "$file" && -s "$file" ]] ; then # File must exist, and not be any of the above.
# You can use any one of these three, listed fastest to slowest
tar -cS --no-recursion --warning=none "$file" &>/dev/null
# cp --preserve=all --reflink=never "$file" /dev/null
# cat "$file" 1>/dev/null
(( FileCnt++ )) # Count of files cache-loaded
else
(( SkipCnt++ )) # Count of any files not otherwise processed.
fi
我试图将其转换为 case 语句,但我无法弄清楚...我到目前为止得到的是什么(我只是将每个 if 语句复制到 case 语句中,但它一直引发错误):
错误:
/usr/local/bin/cachewarmup: line 43: syntax error near unexpected token `"$file"'
/usr/local/bin/cachewarmup: line 43: ` [[ "$file" =~ ^($OP0|$OP1|$OP2|$OP3|$OP4|$OP5|$OP6|$OP7|$OP8|$OP9)$ ]]) (( SkipCnt++ ));;'
(不起作用的)代码:
for file in $(find $1 -maxdepth 10000 -xdev -ignore_readdir_race); do
case true in
[[ "$file" =~ ^($OP0|$OP1|$OP2|$OP3|$OP4|$OP5|$OP6|$OP7|$OP8|$OP9)$ ]]) (( SkipCnt++ ));;
[[ ! -e "$file" ]]) (( StalCnt++ ));;
[[ ! -s "$file" ]]) (( ZeroCnt++ ));;
[[ -d "$file" ]]) (( DirCnt++ ));;
[[ -h "$file" || -L "$file" ]]) (( LinkCnt++ ));;
[[ -c "$file" ]]) (( CdevCnt++ ));;
[[ -b "$file" ]]) (( BdevCnt++));;
[[ -p "$file" ]]) (( PipeCnt++));;
[[ -S "$file" ]]) (( SockCnt++ ));;
[[ -f "$file" && -s "$file" ]]) tar -cS --no-recursion --warning=none "$file" &>/dev/null; (( FileCnt++ ));;
*) (( SkipCnt++ ));;
esac
对我做错的事情有什么想法吗?
答案1
您的案例if
和case
case something in
解释为字符串,而something
不是命令。something
固定的像 这样的字符串true
。
通常这里会用到变量。它提供一个非固定字符串,用于与代码中稍后出现的模式进行比较。
在你原来的代码逻辑中,没有这样的变量。你的测试是命令(好吧,[[
是一个 shell 关键字,严格来说不是命令;但它仍然像命令一样返回退出状态,完全不是字符串)。如果所有命令都尝试将某个变量的值与某些模式进行比较,那么它们可能可以转换为case … esac
。在您的命令中,带有 的命令=~
执行此操作,但其余的命令执行其他操作。这实际上不符合转换为 的条件case … esac
。
一般情况下,即使是测试也=~
可能或者可能不会符合转换为的条件case … esac
。问题是=~
使用正则表达式,而的模式case
不是正则表达式;通常,可能无法将一种方案严格转换为另一种方案。
坚持if … elif … fi
,不要尝试转换为不适合的语法。
更广阔的视野if
和case
if
取决于返回退出状态的某些 shell 代码的退出状态。它可能是命令(如grep
或[
)或其他东西(如[[
或 管道),像命令一样返回退出状态。基本上在if
(或elif
)之后,您可以放置随意的shell 代码作为条件。
case
直接比较字符串。它不依赖于任何事物的退出状态。虽然原则上你可以将字符串比较(case
)转换为实现相同字符串比较的 shell 代码( for if
),但转换随意的shell 代码 ( if
) 与字符串比较 ( case
) 非常麻烦(如果可能的话)。