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

MacOS下source .zshrc出现Bad Math Expression错误求助

问题描述

我希望在macOS或Linux系统中,用户执行source ~/.zshrc时展示认证令牌的过期时间。直接在zsh中运行相关代码一切正常,但在macOS下执行source ~/.zshrc时抛出错误:

└─> source ~/.zshrc
check_token:35: bad math expression: operator expected at `23:17:10'

错误指向代码行:

ISO_expiry_date="${expiry_year}/${expiry_month}/${expiry_day}${expiry_time}"

完整的check_token函数代码如下:

check_token() {
  command="auth"

  token -s
  if [ $? -ne 0 ]; then  
    echo "Authetication not present, running $command"
    eval $command
    if [[ $? -ne 0 ]] && [[ $? -ne 130 ]]; then
      check_token
    fi
  fi

  token -s
  if [ $? -eq 0 ]; then
    token=`tokenlist | grep string`
    ISO_expiry_date=""

    if [[ `uname` == "Linux" ]]; then
      expiry_date=`echo $token | awk '{print $3}'`
      # 从美式日期格式转为ISO格式
      expiry_date_parts=(${(s[/])expiry_date})
      expiry_time=`echo $token | awk '{print $4}'`
      ISO_expiry_date="$expiry_date_parts[3]/$expiry_date_parts[2]/$expiry_date_parts[1] $expiry_time"
    elif [[ `uname` == "Darwin" ]]; then
      expiry_day=`echo $token | awk '{print $6}'`
      printf -v expiry_day "%02d" $expiry_day
      month=`echo $token | awk '{print $5}'`
      expiry_month=`date -j -f "%b" "$month" +"%m"`
      expiry_year=`echo $token | awk '{print $8}'`

      expiry_time=" `echo $token | awk '{print $7}'`"

      ISO_expiry_date="${expiry_year}/${expiry_month}/${expiry_day}${expiry_time}"
    fi

    if [[ $ISO_expiry_date -ne "" ]]; then
      echo "Ticket will expire at $ISO_expiry_date"
    else
      echo "Current ticket: $token"
    fi
  fi
}

macOS下tokenlist的输出示例:

Issued                Expires               Principal
Sep  1 13:17:14 2022  Sep  1 23:17:10 2022  string

环境版本信息:

  • zsh版本:
zsh --version
zsh 5.8.1 (x86_64-apple-darwin21.0)
  • macOS版本:
sw_vers
ProductName:    macOS
ProductVersion: 12.5.1
BuildVersion:   21G83
问题修复

错误原因

报错的根本原因不是ISO_expiry_date的赋值行,而是后续的判断语句if [[ $ISO_expiry_date -ne "" ]]:-ne是数值比较运算符,zsh会尝试将字符串格式的ISO_expiry_date解析为数值,遇到时间中的冒号:时无法识别,从而抛出"bad math expression"错误。

修复步骤

将数值比较运算符-ne替换为字符串比较运算符!=,修改后的判断代码:

if [[ $ISO_expiry_date != "" ]]; then
  echo "Ticket will expire at $ISO_expiry_date"
else
  echo "Current ticket: $token"
fi

可选优化

可以优化macOS分支的代码,减少重复调用awk的次数,一次性提取所有需要的字段:

elif [[ `uname` == "Darwin" ]]; then
  # 用awk一次性提取过期时间的日、月、时间、年
  read expiry_day month expiry_time expiry_year <<< $(echo $token | awk '{print $6, $5, $7, $8}')
  printf -v expiry_day "%02d" $expiry_day
  expiry_month=$(date -j -f "%b" "$month" +"%m")
  ISO_expiry_date="${expiry_year}/${expiry_month}/${expiry_day} ${expiry_time}"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 21:06:19