华为云CodeArts CLI踩坑记:crontab定时任务认证失败?原来是它在捣鬼
前言
之前安装了华为云的CodeArts CLI(码道CLI),在终端手动跑 codearts run 用得挺顺手。于是想着更进一步,把它接入crontab定时任务。
结果定时任务跑了之后看日志,傻眼了——报的是"认证失败,没有设置环境变量CODEARTS_CLI_AK/CODEARTS_CLI_SK"。但我明明在终端手动执行是正常的啊,同样的AK/SK,同一个脚本,为什么定时任务就跪了?
这篇文章记录这个问题的排查过程和最终解决方案。
背景:AK/SK的配置方式
CodeArts CLI需要AK/SK认证才能使用。按照官方文档指引,在华为云控制台申请AK/SK后,通过环境变量配置:
export CODEARTS_CLI_AK="你的AK"
export CODEARTS_CLI_SK="你的SK"
为了方便以后每次登录都能直接用,我把它写进了 ~/.bashrc:
# ~/.bashrc
export PATH="$HOME/.codeartsdoer/installers/bin:$PATH"
export CODEARTS_CLI_AK="AKIDxxxxxxxxxxxxx"
export CODEARTS_CLI_SK="xxxxxxxxxxxxxxxxxxxxx"
手动登录终端测试:
codearts run "解释一下什么是变量"
一切正常,AI秒回,信心满满地配好了cron。
问题出现
crontab配置很简单,每天定时调一个shell脚本:
# crontab
0 6 * * * cd /home/user/codearts && bash run.sh >> logs/cron.log 2>&1
脚本内容也很直接:
#!/bin/bash
# run.sh
codearts run "今天天气怎么样"
第二天看日志:
认证失败,没有设置环境变量CODEARTS_CLI_AK/CODEARTS_CLI_SK
请在华为云统一身份认证页面申请AK/SK,通过配置环境变量的方式使用cli命令。
那一刻我是困惑的:同样的AK/SK,终端执行好好的,cron执行就报没配置?
排查过程
第一步,确认AK/SK没写错——echo $CODEARTS_CLI_AK 终端里有值,没问题。
第二步,确认PATH对不对——which codearts 能找到,PATH也没问题。
第三步,灵光一闪——会不会是cron的环境跟终端不一样?
于是改了下脚本,在开头加一行打印当前环境变量:
#!/bin/bash
env > /tmp/cron_env.txt
codearts run "你好"
等cron跑完后查看 /tmp/cron_env.txt,发现里面确实没有 CODEARTS_CLI_AK 和 CODEARTS_CLI_SK。
根因确认了:crontab执行任务时,不会自动加载用户的 ~/.bashrc 文件。
为什么会这样?
这是Linux基础知识,但我当时确实没想到。简单科普一下:
- 交互式shell(你手动SSH登录的终端):会依次加载
/etc/profile、~/.bash_profile、~/.bashrc等配置文件,所有export的环境变量都生效 - crontab执行的shell:启动的是非交互式、非登录shell,只加载极少量系统变量(
HOME、LOGNAME、PATH等),不会 source 用户的.bashrc
所以AK/SK虽然在 .bashrc 里写好了,但cron根本看不到它。
解决方案
既然cron不加载 .bashrc,那我们就让它在脚本里手动加载。
方法一(推荐):精确提取AK/SK
不直接source整个 .bashrc(可能引入副作用),而是只提取需要的变量:
#!/bin/bash
# 1. 加载CLI路径
export PATH="$HOME/.codeartsdoer/installers/bin:$PATH"
# 2. 从 .bashrc 提取AK/SK(cron不会自动source .bashrc)
export $(grep 'CODEARTS_CLI_AK\|CODEARTS_CLI_SK' $HOME/.bashrc | xargs)
# 3. 正常执行
codearts run "你的问题"
grep 从 .bashrc 中搜索包含 CODEARTS_CLI_AK 或 CODEARTS_CLI_SK 的行,xargs 把它拼成 export KEY=VALUE 的形式。
方法二:直接source(简单但有风险)
#!/bin/bash
source ~/.bashrc
codearts run "你的问题"
简单粗暴,但如果 .bashrc 里有输出语句或者不适合在非交互环境执行的命令,可能会出奇怪的问题。
方法三:单独配置文件
把敏感信息从 .bashrc 中提取出来,放在一个独立的配置文件中:
# ~/.codearts_cli_env (只有AK/SK,不参与交互式shell加载)
export CODEARTS_CLI_AK="你的AK"
export CODEARTS_CLI_SK="你的SK"
然后在脚本中:
#!/bin/bash
export PATH="$HOME/.codeartsdoer/installers/bin:$PATH"
source ~/.codearts_cli_env
codearts run "你的问题"
三种方法各有利弊,我目前用的是方法一,精确可控。
拓展:多个账号怎么处理?
如果你有多个华为云账号的AK/SK(比如大小号),命名时加后缀区分:
# .bashrc
export CODEARTS_CLI_AK_2="第二个账号的AK"
export CODEARTS_CLI_SK_2="第二个账号的SK"
对应的grep也要调整:
# 匹配 _2 后缀的变量,同时用 sed 去掉 _2 后缀重命名为标准变量名
export $(grep -E 'CODEARTS_CLI_(AK|SK)_2' $HOME/.bashrc | sed 's/_2//' | xargs)
这个正则要点:grep -E 开启扩展正则,(AK|SK) 精确匹配,sed 's/_2//' 去掉后缀。
总结
这个问题本质上不是CodeArts CLI的锅,而是crontab的通用机制。任何依赖用户环境变量的命令,放进cron都会遇到同样的情况。
如果再遇到"终端能跑、cron不能跑"的问题,第一反应就应该是——检查环境变量。大概率是cron没有source你的配置文件。
希望这篇文章帮你少踩一个坑。下一篇我会聊一个更隐蔽的问题:明明认证失败,CLI的退出码为什么还是0?
- 点赞
- 收藏
- 关注作者
评论(0)