Shell脚本对比目录文件时find报错:目录存在却提示找不到
解决Shell脚本中
find报错"cannot search : No such file or directory"的问题 你的脚本出现这个错误,主要是变量引用失效和语法错误导致的,我来一步步拆解问题并给出修正方案:
报错的核心原因
- 变量间接引用在子shell中无法识别:你用
bash -c启动了子shell,但子shell没法解析父shell里的${!A}这种间接引用语法,会把它当成空字符串,所以find命令实际执行的是find "",自然会报找不到路径的错误。 - 目录判断语法错误:
if [ d ${!A} ]; then是错误的写法,正确的目录存在判断应该是if [ -d "${!A}" ]; then,少了-符号会导致条件判断完全失效,不管目录是否存在都会执行后续代码。 - 路径替换逻辑错误:第二个
diff里的sed "s:${!A}::"写错了,应该替换B目录的路径,否则生成的文件路径会混乱。
修正后的完整脚本
#!/bin/sh set -e A_DIR_1=/tmp/1 A_DIR_2=/tmp/2 A_DIR_3=/tmp/3 B_DIR_1=/tmp/1 B_DIR_2=/tmp/2 B_DIR_3=/tmp/3 for i in {1..3} do A="A_DIR_$i" B="B_DIR_$i" # 先验证两个目录都存在,避免单目录不存在时出错 if [ -d "${!A}" ] && [ -d "${!B}" ]; then # 把间接引用的目录路径赋值给普通变量,避免后续引用问题 a_dir="${!A}" b_dir="${!B}" # 提取A存在但B不存在的文件,追加到fileA diff -u <(find "$b_dir" | sed "s:^$b_dir::") <(find "$a_dir" | sed "s:^$a_dir::") \ | sed "/^+\//!d; s::${a_dir}/:" >> /tmp/fileA # 提取B存在但A不存在的文件,追加到fileB diff -u <(find "$a_dir" | sed "s:^$a_dir::") <(find "$b_dir" | sed "s:^$b_dir::") \ | sed "/^+\//!d; s::${b_dir}/:" >> /tmp/fileB fi done
关键修正说明
- 修复目录判断:加上了
-d参数和引号,同时增加了对B目录的存在判断,确保只有两个目录都存在时才执行比较逻辑。 - 简化变量引用:把间接引用的目录先赋值给普通变量
a_dir和b_dir,既避免了子shell的变量访问问题(这里直接去掉了没必要的bash -c),也让代码更易读。 - 优化路径替换:给
sed的替换规则加上^锚定字符串开头,避免误替换路径中间的相同字符,同时修正了第二个diff里的替换目标。
内容的提问来源于stack exchange,提问作者methuselah
相关产品推荐
相关产品推荐

