欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

左尖括号 空格 左尖括号 与 两个左尖括号的区别 AG chatgpt 有大用 有大大用

while IFS= read -r -d '' file; do

    if [[ "$file" != /Library/* && "$file" != /System/Library/* ]]; then

        files+=("$file")

    fi

done < <(mdfind '((kMDItemFSName == "*AAAA*"cd) || (kMDItemFSName == "*BBBB*"cd) || (kMDItemFSName == "*CCCC*"cd) || (kMDItemFSName == "*DDDD*"cd) || (kMDItemFSName == "*EEEE*"cd)) && ((kMDItemFSName == "*.pdf"cd) || (kMDItemFSName == "*.ppt"cd) || (kMDItemFSName == "*.pptx"cd) || (kMDItemFSName == "*.key"cd) || (kMDItemFSName == "*.png"cd) || (kMDItemFSName == "*.jpg"cd) || (kMDItemFSName == "*.jpeg"cd))' -0)

  while IFS= read -r -d '' file; do

    if [[ "$file" != /Library/* && "$file" != /System/Library/* ]]; then

        files+=("$file")

    fi

done <<(mdfind '((kMDItemFSName == "*AAAA*"cd) || (kMDItemFSName == "*BBBB*"cd) || (kMDItemFSName == "*CCCC*"cd) || (kMDItemFSName == "*DDDD*"cd) || (kMDItemFSName == "*EEEE*"cd)) && ((kMDItemFSName == "*.pdf"cd) || (kMDItemFSName == "*.ppt"cd) || (kMDItemFSName == "*.pptx"cd) || (kMDItemFSName == "*.key"cd) || (kMDItemFSName == "*.png"cd) || (kMDItemFSName == "*.jpg"cd) || (kMDItemFSName == "*.jpeg"cd))' -0)

区别



这两个代码片段的区别在于 done 行末的 进程替换(Process Substitution) 语法写法不同:

1. 正确写法(第一个示例)< 空格<

bash    
done < <(mdfind ... -0)    


  • <(mdfind ... -0) 是一个 进程替换,它会将 mdfind 命令的输出作为一个临时文件描述符传递给 while 循环。

  • 前面的 < 是标准输入重定向,表示从 <(mdfind ...) 的结果读取数据。

  • 为什么正确?

    • <(command) 生成一个类似 /dev/fd/63 的文件描述符,供 while 循环逐行读取。

    • -0 选项让 mdfind 输出以 \0(NULL 字符)分隔,而 IFS= read -r -d '' 能够正确解析这种格式,避免文件名含空格或换行符时的解析错误。

2. 错误写法(第二个示例) <<

bash    
done <<(mdfind ... -0)    


  • 这里 <<( 缺少空格,使得 shell 解析错误。

  • 可能被解释为:

    • << 被当作 here-document(嵌入式文档) 的开始,但后面没有匹配的结束标记(如 EOF)。

    • 或者,<<( 被当作一个无效的语法,直接报错(bash 会提示语法错误)。

关键区别总结

  • 正确形式< <(command) → 先进程替换 <(...),再输入重定向 <,中间必须加空格。

  • 错误形式<<(...) → shell 无法识别,要么解析成 here-document(失败),要么直接报错。

正确代码的作用

这段代码的目的是:

  1. 用 mdfind 搜索 文件名包含 AAAABBBBCCCCDDDD 或 EEEE,且扩展名是 .pdf/.ppt/.pptx/.key/.png/.jpg/.jpeg 的文件。

  2. 排除系统目录:跳过 /Library/ 和 /System/Library/ 下的文件。

  3. 安全处理文件名-0 和 IFS= read -r -d '' 确保即使文件名含空格或换行符也能正确读取。

如果你的代码写成 <<(...),bash 会报错,改为 < <(...) 即可正常运行。



 


普通分类: