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

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" {} +

关键修改说明

  1. 变量传递:将外层的logpath和donotdelete作为参数传递给sh -c的子shell,在子shell内部通过位置参数$1、$2获取,避免单引号对变量解析的阻止。
  2. 参数优化:把deletepath改为用${1:-path}定义,支持通过脚本第一个参数传入目标路径,默认值保留原硬编码的path,提升灵活性。
  3. 日志文件复用:原代码生成了带时间戳的filename但未使用,修改后将logpath指向该文件,每次运行生成独立日志,避免日志内容混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 03:49:56