在AppleScript中调用Bash脚本查找序列缺失文件问题排查
问题分析与解决方案
让我们一步步拆解你遇到的问题,然后给出修复后的代码和更简便的实现思路:
核心问题排查
你遇到的两个错误,本质上都是AppleScript调用shell脚本时的环境/语法兼容问题:
- 误报"00000 is missing":当shell用默认的
sh而非bash执行时,extglob扩展不生效,导致数组arr为空,${arr[0]%.*}会被解析为空值,10#强制十进制转换时会把空值当成0,循环从0开始就会误报。 - "arr: bad array subscript"错误:同样是因为
#!/bin/bash的位置不对,脚本用sh执行,不支持bash的数组扩展语法;再加上路径转义错误,导致cd到错误目录,没有匹配到任何文件,数组为空后访问下标就会报错。
修复后的AppleScript代码
下面是修正了所有问题的版本,每一步都做了优化:
set AEPname to "AO-M1P8" -- 拼接完整目标路径,用POSIX路径自动转换冒号分隔符 set renderPath to POSIX path of ("Volumes:RAID STORAGE:CACHES:RENDERS:AE:" & AEPname) -- 构造标准bash脚本,确保所有语法生效 set shellScript to "#!/bin/bash # 切换目录失败直接退出,避免后续错误 cd " & quoted form of renderPath & " || exit 1 # 启用bash扩展特性 shopt -s extglob nullglob # 匹配所有数字命名的psd文件 arr=( +([0-9]).psd ) # 先检查是否有匹配的文件,避免空数组报错 if [[ ${#arr[@]} -eq 0 ]]; then echo \"No PSD files found in the directory\" exit 0 fi # 提取起始和结束编号,用10#强制十进制解析(避免0开头的八进制问题) startNum=$((10#${arr[0]%.*})) endNum=$((10#${arr[-1]%.*})) # 遍历编号序列检查缺失 for ((i=startNum; i<=endNum; i++)); do printf -v f \"%05d\" \"$i\" # 直接检查文件,不需要多余的echo子shell if [[ ! -f \"$f\".psd ]]; then echo \"$f is missing\" fi done" # 执行shell脚本并获取结果 set ISAEDONE to do shell script shellScript display dialog ISAEDONE as text # 可选的结果判断逻辑 if ISAEDONE contains "is missing" or ISAEDONE contains "No PSD files found" then display dialog "FILE ISSUE DETECTED" else display dialog "ALL FILES ARE PRESENT" end if
关键修复点说明
- Shebang放在第一行:确保
do shell script用bash执行,而非默认的sh,这样extglob和数组语法才能正常工作。 - 路径自动转义:用
quoted form of renderPath处理路径中的空格和特殊字符,手动转义容易出错。 - 空数组预检查:提前判断是否有匹配文件,避免数组下标访问错误。
- 简化文件检查:去掉多余的
$(echo "$f".*),直接用"$f".psd即可,更高效。
更简便的实现思路
如果追求更简洁的逻辑,可以用seq生成预期编号,再和现有文件对比:
set AEPname to "AO-M1P8" set renderPath to POSIX path of ("Volumes:RAID STORAGE:CACHES:RENDERS:AE:" & AEPname) set shellScript to "#!/bin/bash cd " & quoted form of renderPath & " || exit 1 shopt -s nullglob # 提取所有文件的编号并排序 nums=($(printf '%s\n' +([0-9]).psd | sed 's/\\.psd$//' | sort -n)) if [[ ${#nums[@]} -eq 0 ]]; then echo \"No PSD files found\" exit 0 fi # 生成从起始到结束的所有编号,对比是否存在 seq -f \"%05g\" \"${nums[0]}\" \"${nums[-1]}\" | while read -r f; do [[ ! -f \"$f\".psd ]] && echo \"$f is missing\" done" set ISAEDONE to do shell script shellScript display dialog ISAEDONE as text
这个版本用sed提取编号,sort排序,再用seq生成所有预期编号,逻辑更直观,也避免了bash循环的一些细节问题。
内容的提问来源于stack exchange,提问作者David Escalante
相关产品推荐
相关产品推荐

