You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 12:10:33