Shell脚本执行正常但无法查找/删除旧文件及生成日志求助
旧文件清理脚本问题排查与修复
针对脚本执行后无有效日志、无法删除文件且报Failed to find files错误的问题,从以下几个方向排查修复:
1. 修正find命令的错误判断逻辑
find命令的返回值规则容易被误解:即使没有找到匹配的文件,返回值仍然是0,只有当出现权限不足、目录不存在等真正的执行错误时,才会返回非0。你看到的错误日志,说明find命令确实执行失败了,而非没有找到旧文件。
2. 排查目录路径的有效性
- 检查
directories.txt中的路径是否存在多余的空格、换行或制表符,这些会导致mapfile读入无效路径。可以先清理文件:sed -i '/^[[:space:]]*$/d; s/[[:space:]]*$//' /path/to/directories.txt - 确认文件中的路径没有被多余的引号包裹(比如写的是
"/data/my dir"),否则directory变量会包含引号,导致find无法识别目录。
3. 确保日志路径的可写性
脚本无法生成日志,大概率是日志文件的父目录不存在或无写入权限:
- 在脚本开头添加目录自动创建逻辑,确保日志目录存在:
for log_path in "$log_file" "$runtime_log_file"; do log_dir=$(dirname "$log_path") [ -d "$log_dir" ] || mkdir -p "$log_dir" done - 验证运行用户(包括root)对日志路径有写入权限,避免挂载点为只读或权限限制。
4. 验证-mtime +30的匹配逻辑
-mtime +30匹配的是修改时间超过30天整的文件(即31天及以上),如果你的文件都在30天以内,find不会返回结果,但不会触发错误日志。可以临时改用-mtime +29测试,或者用分钟数精确计算:
find "$directory" -type f -mmin +$((30*24*60))
5. 开启调试模式定位问题
在脚本第一行#!/bin/bash下方添加set -x,开启调试输出,执行时会打印每一步的命令和参数,能直接看到find实际处理的路径是否正确,快速定位问题点。
修复后的完整脚本
整合上述修复点后的脚本示例:
#!/bin/bash set -euo pipefail directories_file="/path/to/directories.txt" log_file="/path/to/log/file.txt" runtime_log_file="/path/to/runtime/log/file.txt" # 确保日志目录存在 for log_path in "$log_file" "$runtime_log_file"; do log_dir=$(dirname "$log_path") if [ ! -d "$log_dir" ]; then mkdir -p "$log_dir" || { echo "Failed to create log directory $log_dir"; exit 1; } fi done # 检查目录文件是否存在 if [ ! -f "$directories_file" ]; then echo "Error: Directories file not found." >> "$runtime_log_file" exit 1 fi # 读取目录列表,过滤空行和首尾空格 mapfile -t directories < <(sed '/^[[:space:]]*$/d; s/[[:space:]]*$//' "$directories_file") start_time=$(date +%s) log_step() { local timestamp=$(date '+%Y-%m-%d %H:%M:%S') echo "[$timestamp] $1" >> "$runtime_log_file" } for directory in "${directories[@]}"; do if [ ! -d "$directory" ]; then log_step "Error: Directory '$directory' not found." continue fi log_step "Scanning files older than 30 days in '$directory'..." # 收集旧文件列表并检查find执行状态 old_files=$(find "$directory" -type f -mtime +30 -print) if [ $? -ne 0 ]; then log_step "Error: find command failed for '$directory'." continue fi # 处理找到的旧文件 if [ -n "$old_files" ]; then echo "$old_files" >> "$log_file" file_count=$(echo "$old_files" | wc -l) log_step "Found $file_count old files, starting deletion..." find "$directory" -type f -mtime +30 -delete if [ $? -eq 0 ]; then log_step "Successfully deleted old files in '$directory'." else log_step "Error: Failed to delete files in '$directory'." fi else log_step "No files older than 30 days found in '$directory'." fi done end_time=$(date +%s) run_time=$((end_time - start_time)) log_step "Script execution completed in $run_time seconds." echo "Script execution completed successfully."
内容的提问来源于stack exchange,提问作者sage
相关产品推荐
相关产品推荐

