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

Bash脚本通配符传参时find搜索结果异常问题求解

问题原因

出现该差异的核心原因是Shell通配符展开发生在命令执行前,且原脚本仅接收了第一个位置参数作为搜索路径:

  • 当你执行convert_mkv_mp4_v3.sh ./U*时,Shell会在脚本启动前就把./U*展开为当前目录下所有以U开头的文件/文件夹路径,这些路径会作为多个独立的位置参数传给脚本,实际执行的命令等价于:
    convert_mkv_mp4_v3.sh "./U2 - Go Home Live from Slane Castle Ireland" "./U2 - Live" "./U2 - Rattle and Hum" "./U2 - The Best of 1990-2000" ... # 其余所有U开头的路径
    
    这些路径依次对应脚本的$1、$2、$3...位置参数。
  • 原脚本的逻辑只判断了$1是否为空,仅把$1赋值给DIR变量,后续find命令只在这第一个路径(也就是./U2 - Go Home Live from Slane Castle Ireland)下搜索mkv文件,其余所有匹配到的U开头目录都被忽略,因此只返回3个结果。
  • 当你把find参数硬编码为./U*时,通配符展开后所有U开头的路径会全部作为find的搜索根目录传入,因此能遍历到所有17个mkv文件。

另外原脚本还存在一个隐患:find ${DIR}写法没有给变量加引号,一旦路径包含空格、特殊字符会出现解析错误。

修复方法

调整脚本逻辑,让它支持接收多个传入路径作为搜索根,同时给变量加引号规避特殊字符问题,修改后的完整代码如下:

#!/bin/bash
# 未传入路径时默认使用当前目录
if [ $# -eq 0 ]; then
  search_dirs=(.)
else
  search_dirs=("$@")
fi

arrayname=()
while IFS= read -d '' -r filename; do
    arrayname+=("$filename")
done < <(find "${search_dirs[@]}" -name '*.mkv' -print0)
printf "%s\n" "${arrayname[@]}"

核心修改点:

  • 用$#判断传入参数总数,替代原有仅判断$1是否为空的逻辑,适配无参数、多参数两种场景
  • 用数组search_dirs接收所有传入的位置参数"$@",不会遗漏通配符展开后生成的多个路径
  • 所有变量、数组展开时都用双引号包裹,兼容带空格、特殊字符的文件路径
  • find命令直接接收所有搜索路径作为参数,实现多目录下的mkv文件遍历

内容的提问来源于stack exchange,提问作者rnng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:48:19