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

zsh中date工具报错‘ranged: Cannot apply date adjustment’的问题排查

遍历某月每一天的zsh脚本错误分析与解决

问题场景

编写zsh脚本遍历某月每一天,简化后的代码如下:

for i in range {1..31}; do 
  dstring=$( date -v${i}d ) ; 
  echo ${dstring}; 
done

执行后能输出预期的日期列表,但会先抛出错误:

ranged: Cannot apply date adjustment
usage: date [-jnRu] [-I[date|hours|minutes|seconds]] [-f input_fmt]
            [-r filename|seconds] [-v[+|-]val[y|m|w|d|H|M|S]]
            [[[[mm]dd]HH]MM[[cc]yy][.SS] | new_date] [+output_fmt]

Thu  1 May 2025 17:09:05 BST
Fri  2 May 2025 17:09:05 BST
...(省略中间日期)
Fri 30 May 2025 17:09:05 BST

调整大括号的取值范围(如{4..5})后,错误依然出现,但日期输出正常。

错误原因

错误根源是循环语句里多写了冗余的range关键词:

  • zsh中{1..31}本身是大括号扩展语法,直接会生成1到31的数字序列,不需要额外加range。
  • 当你写for i in range {1..31}时,循环的第一个元素是字符串range,而非数字。第一次循环执行date -v${i}d时,会变成date -vranged,date命令无法识别ranged这个无效的调整参数,因此抛出错误。
  • 后续循环处理1到31的数字时,参数合法,所以能正常输出日期。

解决方法

1. 移除冗余的range关键词

直接使用大括号扩展生成数字序列,修正后的代码:

for i in {1..31}; do 
  dstring=$( date -v${i}d ) ; 
  echo ${dstring}; 
done

这样循环元素只有1到31,不会触发无效参数错误。

2. 严谨遍历当月实际天数(可选)

如果需要严格遍历当前月份的每一天,避免处理超出当月天数的日期(比如4月只有30天,date -v31d会跳到5月1日),可以先获取当月最后一天再生成序列:

# 获取当月最后一天的数字
last_day=$(date +%d)
# 遍历1到当月最后一天
for i in {1..$last_day}; do
  dstring=$(date -v${i}d)
  echo $dstring
done

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:48:25