Shell脚本中基于文件最后修改时间与当前时间对比创建新文件的时间差值计算问题
问题排查与正确实现方案
首先,咱们来看看你代码里的问题出在哪:你用stat -c %y获取的是人类可读的时间字符串(比如2021-08-03 10:30:56.627022878 -0500),但date +%s返回的是Unix时间戳(从1970年1月1日到现在的秒数)。这俩格式完全不兼容,直接用let做减法时,Shell根本没法把字符串当成数值计算,只能把它当成表达式的一部分拼接起来,这就是你看到奇怪输出的原因。
正确实现方法
方法1:直接用stat获取Unix时间戳(推荐,GNU系统适用)
GNU版本的stat支持%Y(大写Y)参数,它会直接返回文件最后修改时间的Unix时间戳(秒数),这样就能和当前时间戳直接做数值运算了:
# 获取文件最后修改时间的Unix时间戳(秒) LAST_MODIFIED_TIMESTAMP=$(stat -c %Y "${APPDIR}/data/XYZ.csv") # 获取当前时间的Unix时间戳 NOW=$(date +%s) # 计算时间差(秒) diff=$((NOW - LAST_MODIFIED_TIMESTAMP)) echo "时间差(秒):${diff}" # 你的核心逻辑:当文件最后修改时间早于当前时间(可按需加阈值,比如超过1小时) THRESHOLD=3600 # 1小时,单位秒 if [ ${diff} -gt ${THRESHOLD} ]; then # 创建新文件的逻辑,示例: touch "${APPDIR}/data/new_XYZ.csv" echo "已创建新文件,原文件已超过${THRESHOLD}秒未更新" fi
方法2:将时间字符串转成时间戳(兼容BSD等系统)
如果你的系统是BSD(比如macOS),stat可能不支持%Y参数,这时候可以先获取可读时间字符串,再用date命令把它转成时间戳:
# 获取文件最后修改时间的可读字符串,截取日期和时间部分(去掉小数和时区) LAST_MODIFIED_DATE=$(stat -c %y "${APPDIR}/data/XYZ.csv" | cut -d' ' -f1,2) # 将可读时间转成Unix时间戳 LAST_MODIFIED_TIMESTAMP=$(date -d "${LAST_MODIFIED_DATE}" +%s) NOW=$(date +%s) diff=$((NOW - LAST_MODIFIED_TIMESTAMP)) echo "时间差(秒):${diff}" # 同样的判断逻辑 THRESHOLD=3600 if [ ${diff} -gt ${THRESHOLD} ]; then touch "${APPDIR}/data/new_XYZ.csv" echo "已创建新文件,原文件已超过${THRESHOLD}秒未更新" fi
关键知识点
stat -c %y:返回人类可读的最后修改时间字符串stat -c %Y:返回最后修改时间的Unix时间戳(秒数)date +%s:返回当前时间的Unix时间戳$((...)):Shell中用于数值计算的语法,比let更直观通用
内容的提问来源于stack exchange,提问作者Bhanu
相关产品推荐
相关产品推荐

