You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Akamai缓存清理脚本Win10正常,Linux下失效求助

排查Linux下Akamai缓存清理脚本执行失败的问题

看起来你遇到的情况挺棘手——脚本在Windows上能正常完成缓存清理,到Linux上控制台输出和Windows完全一致,但就是没实际生效。结合Shell脚本跨平台的常见坑,我整理了几个大概率的原因和对应的排查、解决步骤:

1. Bash版本不支持declare -n命名引用特性

你的脚本里多处用到了declare -n(比如mk_auth_header函数里的local -n aka_props=$1),这个特性是Bash 4.0及以上版本才支持的。如果你的Linux系统用的是旧版Bash(比如CentOS 6自带的Bash 3.2),这部分代码会直接失效,但可能不会抛出明显报错,导致签名生成错误,Akamai API直接拒绝了你的请求。

排查&解决

  • 先在Linux终端执行bash --version查看版本,如果低于4.0,要么升级Bash,要么修改代码替换declare -n的用法。
  • 举个修改例子,把依赖命名引用的函数改成直接传递参数:
# 原mk_auth_header函数
function mk_auth_header {
 [ "$#" -lt 3 ] && return 1
 local -n aka_props=$1
 local timestamp=$2
 local nonce=$3
 echo -n "EG1-HMAC-SHA256 client_token=${aka_props[client_token]};access_token=${aka_props[access_token]};timestamp=${timestamp};nonce=${nonce};"
}

# 修改后(直接传递所需参数)
function mk_auth_header {
 [ "$#" -lt 4 ] && return 1
 local client_token=$1
 local access_token=$2
 local timestamp=$3
 local nonce=$4
 echo -n "EG1-HMAC-SHA256 client_token=${client_token};access_token=${access_token};timestamp=${timestamp};nonce=${nonce};"
}

# 调用时改为
AUTH_HEADER=$( mk_auth_header "${AKA_PROPS[client_token]}" "${AKA_PROPS[access_token]}" ${TIMESTAMP} ${NONCE} )

2. OpenSSL命令的跨平台输出差异

Windows和Linux的OpenSSL在base64编码的换行处理上有区别:Linux下openssl base64默认每76个字符加换行,而Windows版本可能不会。这会导致签名计算时的字符串不一致,Akamai无法验证你的请求合法性。

解决方法
openssl base64加上-A参数(取消自动换行),修改这两个函数:

function base64_hmac_sha256 {
 [ "$#" -lt 2 ] && return 1
 local key=$1
 local value=$2
 echo -ne "${value}"| openssl sha256 -binary -hmac "${key}" | openssl base64 -A
}

function base64_sha256 {
 [ "$#" -lt 1 ] && return 1
 local value=$1
 echo -ne "${value}" | openssl dgst -binary -sha256 | openssl base64 -A
}

3. 脚本换行符的跨平台问题

如果你的脚本是在Windows上编辑后传到Linux的,可能带有Windows的CRLF换行符(\r\n),而Linux系统期望LF(\n)。虽然多数情况下Shell能兼容,但某些命令(比如sed、awk)会把\r当成普通字符,导致变量值异常(比如签名里多了隐形的\r字符)。

排查&解决

  • cat -A your_script.sh查看脚本,每行末尾如果有^M就是CRLF问题。
  • dos2unix your_script.sh转换换行符,或者在Vim里执行:set fileformat=unix后保存。

4. Curl命令的转义陷阱

脚本最后通过echo curl ... | bash -x的方式执行命令,这里的引号转义在Linux下可能出问题——比如-d \'${BODY}\'可能被解析成带单引号的参数,而不是把BODY内容作为POST数据传递。

优化方法
直接执行curl命令,避免通过echo管道转义,修改最后一段代码:

curl -s -H "Expect:" \
 -H "User-Agent:${P_NAME}" \
 -H "Accept:${H_JSON}" \
 -H "${H_JSON}" \
 -H "${SIGNED_AUTH_HEADER}" \
 -X POST -d "${BODY}" "${DATA_TO_SIGN[scheme]}://${DATA_TO_SIGN[host]}${DATA_TO_SIGN[request_uri]}" | jq .

5. 查看隐藏的错误详情

虽然你说控制台输出一致,但可能Linux下curl的错误被-s参数隐藏了。可以去掉-s换成-v,让curl输出详细的HTTP请求日志,直接看Akamai返回的错误信息(比如签名无效、权限不足、请求格式错误等):

curl -v -H "Expect:" \
 -H "User-Agent:${P_NAME}" \
 -H "Accept:${H_JSON}" \
 -H "${H_JSON}" \
 -H "${SIGNED_AUTH_HEADER}" \
 -X POST -d "${BODY}" "${DATA_TO_SIGN[scheme]}://${DATA_TO_SIGN[host]}${DATA_TO_SIGN[request_uri]}"

内容的提问来源于stack exchange,提问作者S.Kav

火山引擎 最新活动