Cron任务中Shell脚本查找最大.ark文件失败求助
搞定Cron环境下ARK文件恢复脚本的异常问题
嘿,我仔细看了你的脚本和遇到的问题,发现核心有两个关键点:你的文件排序逻辑其实是错的,再加上Cron的执行环境和终端不一样,才导致了这些奇怪的现象。咱们一步步来解决:
先说说你原脚本里的致命逻辑错误
你原本想找体积最大的.ark文件,但那段find命令是对文件路径的字符串做逆序排序,根本不是按文件大小排序!终端里可能刚好巧合让最大的文件路径排到第一(比如文件名带日期,逆序后最新的大文件在前面),但这完全不可靠,Cron环境下的路径差异直接把这个问题暴露出来了。
再说说Cron的环境差异坑
Cron的执行环境没有终端的那些交互式变量:
- 默认工作目录是你的用户home目录,不是脚本所在的目录
$PWD的取值在Cron里不会像终端那样跟着cd命令实时更新(或者说依赖$PWD本身就不稳定)- 环境变量PATH也比终端少很多,某些命令可能找不到
解决方案一步步来
1. 修正find命令,真正按文件大小找最大文件
把原有的find+sort替换成下面的命令,这才是正确获取最大体积文件的方式:
# 查找当前目录下体积最大的.ark文件,只找当前目录不递归子文件夹 actualmap=$(find . -maxdepth 1 -type f -name "*.ark" -printf '%s %p\n' | sort -nr | head -1 | awk '{print $2}')
给你拆解下:
.代表当前工作目录,代替不可靠的$PWD-maxdepth 1避免递归到你的BackupFiles子目录里找文件-printf '%s %p\n'同时输出文件的字节大小和路径sort -nr按数字逆序排序(这样最大的文件直接在第一行)awk '{print $2}'把路径从输出里提取出来
2. 修复Cron的路径问题
在脚本开头明确指定工作目录,并且确保所有操作都基于这个目录,避免依赖Cron的默认路径:
- 把
cd命令改成带错误检查的形式,确保进入目录失败时脚本直接退出 - 尽量用相对当前目录的路径,或者转换为绝对路径,避免歧义
修正后的完整脚本
我给你调整了整个脚本,加上了错误检查和更清晰的日志输出:
#!/bin/bash -e export DISPLAY=:0.0 ##ARK Map Recovery Script # 明确指定工作目录,避免Cron环境的路径混乱 WORK_DIR="/srv/daemon-data/da4aaa1b-0ce9-46d2-bd60-5f599cc089ae/ShooterGame/Saved/SavedArks" # 如果进入目录失败,直接退出脚本,避免后续操作出错 cd "$WORK_DIR" || exit 1 # 检查当前TheIsland.ark的大小 file="TheIsland.ark" echo "=== Checking current map file: $file ===" currentsize=$(wc -c < "$file") echo "Current size: $currentsize bytes" # 查找体积最大的.ark文件 echo -e "\n=== Finding largest .ark file ===" actualmap=$(find . -maxdepth 1 -type f -name "*.ark" -printf '%s %p\n' | sort -nr | head -1 | awk '{print $2}') # 转换为绝对路径,确保后续操作不会出问题 actualmap_abs="$WORK_DIR/$(basename "$actualmap")" echo "Largest file found: $actualmap_abs" biggestsize=$(wc -c < "$actualmap_abs") echo "Largest file size: $biggestsize bytes" # 比较大小并执行恢复逻辑 echo -e "\n=== Starting size comparison ===" if [ "$currentsize" -ge "$biggestsize" ]; then echo "✅ No map recovery needed: current file is larger than or equal to the biggest backup." else echo "⚠️ Current file is smaller than the largest backup! Starting recovery process..." echo "Creating BackupFiles directory if it doesn't exist..." mkdir -p BackupFiles echo "Moving old map file to backup directory..." mv "$file" BackupFiles/ echo "Stopping ARK server..." # 用docker的绝对路径,确保Cron能找到这个命令(可以用which docker查看路径) /usr/bin/docker kill da4aaa1b-0ce9-46d2-bd60-5f599cc089ae echo "Copying largest backup file to replace current map..." cp "$actualmap_abs" "$file" echo "✅ Map recovery completed successfully!" fi
3. 配置Cron时的小技巧
添加Cron任务时,把所有输出重定向到日志文件,方便你排查问题:
# 比如每天凌晨2点执行脚本,日志写到/var/log/ark_recovery.log 0 2 * * * /path/to/your/ark_recovery_script.sh >> /var/log/ark_recovery.log 2>&1
这样不管是正常输出还是错误信息,都会被记录下来,出问题时直接看日志就行。
为啥原脚本在终端能跑?
终端是交互式环境,$PWD就是你当前的工作目录,而且路径字符串的逆序排序刚好让最大的文件排在第一(比如文件名带时间戳),这纯粹是巧合。Cron环境下默认路径不对,直接把这个逻辑错误暴露出来了。
内容的提问来源于stack exchange,提问作者Jamie Tees
相关产品推荐
相关产品推荐

