find -exec sh -c脚本无法识别外部变量的问题求助
问题分析与解决方案
问题1:$logpath未被替换导致权限错误
原代码中sh -c的脚本用单引号包裹,外层shell的变量$logpath不会被解析替换,子shell里$logpath属于未定义状态,重定向操作会试图写入一个字面名为$logpath的文件——如果当前目录没有写入权限,就会触发权限错误。
问题2:if条件判断失效
同理,$donotdelete在单引号内也不会被外层shell替换,子shell中该变量未定义,导致[ "$donotdelete" = "false" ]实际执行的是[ "" = "false" ],判断逻辑完全偏离预期,出现总是输出“deleting files”的异常。
修改后的完整脚本
#!/bin/bash # 建议将deletepath改为第一个参数传入,更灵活 deletepath="${1:-path}" donotdelete="$2" timestamp=$(date +%Y%m%d_%H%M%S) filename="log_${timestamp}.txt" logpath="$filename" find "$deletepath" -maxdepth 5 -exec sh -c ' # 子shell中,$1是日志路径,$2是donotdelete参数,$3及以后是find找到的目标 local logpath="$1" local donotdelete="$2" # 移除前两个自定义参数,剩下的就是find的结果 shift 2 for dir; do # 写入文件修改时间和路径到日志 stat -c "%y %n" "$dir" >> "$logpath" # 正确判断删除开关 if [ "$donotdelete" = "false" ]; then echo "deleting $dir" # 测试无误后,取消下面的注释执行实际删除 # rm -rf "$dir" fi done ' sh "$logpath" "$donotdelete" {} +
关键修改说明
- 变量传递:将外层的
logpath和donotdelete作为参数传递给sh -c的子shell,在子shell内部通过位置参数$1、$2获取,避免单引号对变量解析的阻止。 - 参数优化:把
deletepath改为用${1:-path}定义,支持通过脚本第一个参数传入目标路径,默认值保留原硬编码的path,提升灵活性。 - 日志文件复用:原代码生成了带时间戳的
filename但未使用,修改后将logpath指向该文件,每次运行生成独立日志,避免日志内容混淆。
内容的提问来源于stack exchange,提问作者Hacker
相关产品推荐
相关产品推荐

