Bash脚本中匹配禁止文件路径以跳过外部驱动器文件的问题求助
Bash脚本中匹配禁止文件路径以跳过外部驱动器文件的问题求助
我最近在写一个用来预热ZFS ARC的脚本,最初是用find命令遍历内部驱动器的文件:
for file in $(find "$1" -maxdepth 10000 -xdev -ignore_readdir_race); do
后来在Stack Exchange上有人告诉我这种写法有问题,就改成了while read -r file的方式,同时通过后续代码区分内部和外部驱动器的文件——内部文件用来预热ARC,外部文件只做计数分类。
脚本会把文件分成以下几类:目录、已缓存文件(用来预热ARC的)、符号链接、块设备、字符设备、管道、套接字、零长度文件、跳过文件、失效文件。
现在我卡在跳过文件的匹配逻辑上了:我需要识别出位于外部驱动器路径(比如/media/$USER、/mnt)的文件,把它们计数为“跳过文件”,但试了好几种匹配方法,在终端里测试都正常,放到sudo运行的脚本里就完全不起作用,导致外部的归档文件都被加载到ARC里污染缓存了。
我试过的匹配方法包括:
- 通配符匹配:
if [[ "$file" == *"$OP0"* ]] if [[ "$file" =~ *"$OP0"* ]] - case语句匹配:
case $file in (*$OP0*) SkipCnt++ esac - 自定义
contains函数匹配:if [[ contains "$file" "$OP0" ]] - 正则表达式匹配:
if [[ $file =~ ^($OP0)$ ]] if [[ "$file" =~ ^( "$OP0" || "$OP1" )$ ]] - 文件硬链接比较:
if [[ $file -ef $OP0 ]]
比如这段测试代码在交互式终端里能正确判断/boot/efi/grub/x86_64-efi/gcry_camellia.mod不属于/media/$USER/或/mnt,不会输出任何内容:
OP0=/media/$USER/; OP1=/mnt; OP2=; OP3=; file=/boot/efi/grub/x86_64-efi/gcry_camellia.mod; if [[ "$file" =~ ^( "$OP0" || "$OP1" )$ ]] ; then echo $OP0; echo $OP1; echo $file ; fi
但放到脚本里对应的逻辑:
if [[ "$file" =~ ^( "$OP0" || "$OP1" )$ ]] ; then (( SkipCnt++ ))
就完全失效了——外部驱动器的文件根本没被计数为“跳过文件”,反而被当成普通文件执行了下面的拷贝操作(用来加载到ARC):
# 三种加载方式,从快到慢排序 tar -cS --no-recursion --warning=none "$file" &>/dev/null # cp --preserve=all --reflink=never "$file" /dev/null # cat "$file" 1>/dev/null
想请教各位大佬:我应该用哪种匹配命令,才能让它在sudo运行的脚本里正常工作?
备注:内容来源于stack exchange,提问作者PyNewbie
相关产品推荐
相关产品推荐

