├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── bats-test.yml │ └── linter.yml ├── .gitignore ├── .gitmodules ├── AliyunOpenApiSDK.sh ├── LICENSE ├── README.md ├── examples └── UpdateSSLCert.sh └── test └── test.bats.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 4 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.{yaml,yml}] 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.sh text eol=lf 3 | -------------------------------------------------------------------------------- /.github/workflows/bats-test.yml: -------------------------------------------------------------------------------- 1 | name: Bats test 2 | on: 3 | push: 4 | paths: 5 | - '.github/workflows/bats-test.yml' 6 | - '*.sh' 7 | - 'test/*.sh' 8 | pull_request: 9 | paths: 10 | - '.github/workflows/bats-test.yml' 11 | - '*.sh' 12 | - 'test/*.sh' 13 | 14 | jobs: 15 | test-on-alpine: 16 | runs-on: ubuntu-latest 17 | container: 18 | image: alpine:latest # Test on musl libc 19 | steps: 20 | - name: Install dependencies 21 | run: apk add bash curl git openssl 22 | - name: Bash version 23 | run: bash --version 24 | - name: CURL version 25 | run: curl --version 26 | - name: OpenSSL version 27 | run: openssl version 28 | - name: Check out code 29 | uses: actions/checkout@v4 30 | with: 31 | submodules: true 32 | - name: Run test 33 | env: 34 | AliAccessKeyId: ${{ secrets.ALIACCESSKEYID }} 35 | AliAccessKeySecret: ${{ secrets.ALIACCESSKEYSECRET }} 36 | run: ./test/bats/bin/bats test/test.bats.sh 37 | 38 | test-on-archlinux: 39 | runs-on: ubuntu-latest 40 | container: 41 | image: archlinux:latest # Test on latest version of bash curl openssl 42 | steps: 43 | - name: Install dependencies 44 | run: yes | pacman -Syu --noconfirm bash curl git openssl 45 | - name: Bash version 46 | run: bash --version 47 | - name: CURL version 48 | run: curl --version 49 | - name: OpenSSL version 50 | run: openssl version 51 | - name: Check out code 52 | uses: actions/checkout@v4 53 | with: 54 | submodules: true 55 | - name: Run test 56 | env: 57 | AliAccessKeyId: ${{ secrets.ALIACCESSKEYID }} 58 | AliAccessKeySecret: ${{ secrets.ALIACCESSKEYSECRET }} 59 | run: ./test/bats/bin/bats test/test.bats.sh 60 | 61 | test-on-openwrt: 62 | runs-on: ubuntu-latest 63 | container: 64 | image: openwrt/rootfs:x86-64-openwrt-22.03 65 | steps: 66 | - name: Fix var directory 67 | run: mkdir -p /var/lock 68 | - name: Install dependencies 69 | run: | 70 | opkg update 71 | opkg install git git-http 72 | opkg install bash curl openssl-util 73 | # Bats dependencies 74 | opkg install coreutils-nl 75 | - name: Bash version 76 | run: bash --version 77 | - name: CURL version 78 | run: curl --version 79 | - name: OpenSSL version 80 | run: openssl version 81 | - name: Check out code 82 | if: ${{ github.event.act }} 83 | uses: actions/checkout@v4 84 | with: 85 | submodules: true 86 | - name: Check out code (with git) 87 | if: ${{ !github.event.act }} 88 | run: git clone --depth 1 --recurse-submodules https://github.com/${{ github.repository }}.git /tmp/${{ github.sha }} 89 | - name: Run test 90 | env: 91 | AliAccessKeyId: ${{ secrets.ALIACCESSKEYID }} 92 | AliAccessKeySecret: ${{ secrets.ALIACCESSKEYSECRET }} 93 | run: | 94 | [[ -d /tmp/${{ github.sha }} ]] && cd /tmp/${{ github.sha }} 95 | ./test/bats/bin/bats test/test.bats.sh 96 | 97 | test-on-ubuntu-20_04: 98 | runs-on: ubuntu-20.04 99 | steps: 100 | - name: Update package 101 | run: sudo apt update -y && sudo apt upgrade -y 102 | - name: Install dependencies 103 | run: sudo apt install -y bash curl git openssl 104 | - name: Bash version 105 | run: bash --version 106 | - name: CURL version 107 | run: curl --version 108 | - name: OpenSSL version 109 | run: openssl version 110 | - name: Check out code 111 | uses: actions/checkout@v4 112 | with: 113 | submodules: true 114 | - name: Run test 115 | env: 116 | AliAccessKeyId: ${{ secrets.ALIACCESSKEYID }} 117 | AliAccessKeySecret: ${{ secrets.ALIACCESSKEYSECRET }} 118 | run: ./test/bats/bin/bats test/test.bats.sh 119 | -------------------------------------------------------------------------------- /.github/workflows/linter.yml: -------------------------------------------------------------------------------- 1 | name: Linter 2 | on: 3 | push: 4 | paths: 5 | - '.github/workflows/linter.yml' 6 | - '**.sh' 7 | pull_request: 8 | paths: 9 | - '.github/workflows/linter.yml' 10 | - '**.sh' 11 | 12 | jobs: 13 | shellcheck: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Check out code 17 | uses: actions/checkout@v4 18 | - name: Run ShellCheck 19 | uses: ludeeus/action-shellcheck@master 20 | env: 21 | SHELLCHECK_OPTS: -x 22 | with: 23 | ignore_paths: ./test/bats/** ./test/test_helper/** 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | .idea/ 3 | .DS_Store 4 | .env.dev 5 | .env.local 6 | .env.test 7 | .secrets 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "test/bats"] 2 | path = test/bats 3 | url = https://github.com/bats-core/bats-core.git 4 | [submodule "test/test_helper/bats-support"] 5 | path = test/test_helper/bats-support 6 | url = https://github.com/bats-core/bats-support.git 7 | [submodule "test/test_helper/bats-assert"] 8 | path = test/test_helper/bats-assert 9 | url = https://github.com/bats-core/bats-assert.git 10 | -------------------------------------------------------------------------------- /AliyunOpenApiSDK.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for _aliapi_command in openssl curl; do 4 | if ! command -v $_aliapi_command &> /dev/null; then 5 | echo "Aliyun OpenAPI SDK: $_aliapi_command command not found" >&2 6 | exit 127 7 | fi 8 | done 9 | unset _aliapi_command 10 | 11 | [[ -v ALIYUN_SDK_RUN_ON_MUSL_LIBC ]] || ALIYUN_SDK_RUN_ON_MUSL_LIBC=$(ldd "$SHELL" | grep -q /lib/ld-musl && echo 1 || echo 0) 12 | 13 | ALIYUN_SDK_LAST_HTTP_CODE=0 14 | 15 | # aliapi_rpc [<--key> ...] 16 | aliapi_rpc() { 17 | _aliapi_check_vars || return $? 18 | 19 | if [[ $# -lt 4 ]];then 20 | echo "aliapi_rpc: not enough parameters" >&2 21 | return 2 22 | fi 23 | 24 | local -r _AliAccessKeyId=$AliAccessKeyId _AliAccessKeySecret=$AliAccessKeySecret 25 | 26 | local -u _http_method=$1 27 | local _http_host=$2 28 | local _api_version=$3 29 | local _api_action=$4 30 | shift 4 31 | 32 | local _query_str _signature_nonce _timestamp 33 | _signature_nonce=$(_aliapi_urlencode "$(_aliapi_signature_nonce)") 34 | _timestamp=$(_aliapi_urlencode "$(_aliapi_timestamp_rpc)") 35 | _query_str="AccessKeyId=$_AliAccessKeyId&Action=$_api_action&Format=JSON&SignatureMethod=HMAC-SHA1&SignatureVersion=1.0&SignatureNonce=$_signature_nonce&Timestamp=$_timestamp&Version=$_api_version&" 36 | # 解析其余参数 37 | local _key _value 38 | while [[ $# -ne 0 ]] 39 | do 40 | case $1 in 41 | --*) 42 | if [[ $# -le 1 ]]; then 43 | echo "aliapi_rpc: '$1' has no value" >&2 44 | return 2 45 | fi 46 | _key=${1:2} 47 | _value=$2 48 | [[ $_value =~ .+\(\)$ && $(type -t "${_value:0:-2}") == "function" ]] && _value=$(${_value:0:-2}) 49 | _value=$(_aliapi_urlencode "$_value") 50 | _query_str+="$_key=$_value&" 51 | shift 2 52 | ;; 53 | *) 54 | echo "aliapi_rpc: '$1' is unknown parameter" >&2 55 | return 2 56 | ;; 57 | esac 58 | done 59 | 60 | local _signature 61 | _signature=$(_aliapi_signature_rpc "$_http_method" "${_query_str:0:-1}") 62 | _query_str+="Signature=$(_aliapi_urlencode "$_signature")" 63 | local _curl_out _http_url="https://$_http_host/?$_query_str" 64 | _curl_out=$(curl --location --silent --show-error --request "$_http_method" --write-out "%{http_code}" --connect-timeout 3 "$_http_url") 65 | printf %s "${_curl_out:0:-3}" 66 | ALIYUN_SDK_LAST_HTTP_CODE=${_curl_out:${#_curl_out}-3} 67 | [[ $ALIYUN_SDK_LAST_HTTP_CODE -eq 200 ]] && return 0 || return 1 68 | } 69 | 70 | _aliapi_check_vars() { 71 | if [[ ! -v AliAccessKeyId || ! -v AliAccessKeySecret ]]; then 72 | echo "Aliyun OpenAPI SDK: 'AliAccessKeyId' or 'AliAccessKeySecret' environment variable not found" >&2 73 | return 3 74 | fi 75 | } 76 | 77 | _aliapi_signature_rpc() { 78 | if [[ ${LC_ALL:-X} != C ]]; then 79 | LC_ALL=C _aliapi_signature_rpc "$@" 80 | return $? 81 | fi 82 | 83 | local -u _http_method=$1 84 | local _str=$2 _query_str _sign_str 85 | local _newline=" 86 | " 87 | _str=$(sort <<< "${_str//"&"/"$_newline"}") 88 | _query_str=${_str//"$_newline"/"&"} 89 | _sign_str="$_http_method&$(_aliapi_urlencode "/")&$(_aliapi_urlencode "$_query_str")" 90 | printf "%s" "$_sign_str" | openssl dgst -sha1 -hmac "$_AliAccessKeySecret&" -binary | openssl base64 -e 91 | } 92 | 93 | _aliapi_timestamp_rpc() { 94 | # ISO8601 UTC 95 | date -u -Iseconds 96 | } 97 | 98 | _aliapi_signature_nonce() { 99 | local nonce="" 100 | if [[ -f /proc/sys/kernel/random/uuid ]]; then 101 | nonce=$( [<--key> ...]" >&2 137 | exit 2 138 | fi 139 | 140 | case $1 in 141 | --rpc) 142 | shift 143 | aliapi_rpc "$@" 144 | ;; 145 | *) 146 | echo "Aliyun OpenAPI SDK: '$1' is unknown parameter" >&2 147 | exit 2 148 | ;; 149 | esac 150 | fi 151 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-present Zhong Lufan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Aliyun OpenAPI Bash SDK 2 | 3 | [![Bats test](https://github.com/Hill-98/aliyun-openapi-bash-sdk/actions/workflows/bats-test.yml/badge.svg)](https://github.com/Hill-98/aliyun-openapi-bash-sdk/actions/workflows/bats-test.yml) 4 | 5 | 这是一个非官方的阿里云 OpenAPI Bash SDK,用于 Bash 脚本调用阿里云 OpenAPI,相较于 [aliyun-cli](https://github.com/aliyun/aliyun-cli) 更加轻量,适合小存储设备。 6 | 7 | 理论上支持所有阿里云 RPC OpenAPI,暂不支持 RESTful OpenAPI,将来可能会支持。 8 | 9 | > 这可能是最好用的 Aliyun OpenAPI Bash SDK 10 | 11 | ## 依赖 12 | 13 | * coreutils (`date`) # 获取时间戳 14 | * curl # 网络请求 15 | * openssl # 计算 HAMC-SHA1 签名 16 | 17 | ### 可选依赖 18 | 19 | * ldd # 检查当前 Shell 是否使用 musl libc 20 | * coreutils (`grep`) # 检查当前 Shell 是否使用 musl libc 21 | 22 | > 由于 glibc 和 musl libc 之间的差异,SDK 内部针对这两个不同的库做了些处理,初始化时使用 ldd 检查当前 Shell 是否使用了 musl libc。 23 | > 如果需要跳过检查,可以在导入之前设置变量: `ALIYUN_SDK_RUN_ON_MUSL_LIBC`,`1` 表示使用了 musl libc,`0` 表示没有使用。 24 | 25 | ## 使用 26 | 27 | 1. 声明变量 `AliAccessKeyId` 和 `AliAccessKeySecret` 28 | 2. 导入 `AliyunOpenApiSDK.sh` 29 | 3. 调用 `aliapi_rpc` 函数 30 | 31 | 函数签名: 32 | ```bash 33 | # Output: JsonString 34 | # Retrun Code: 0 = ALIYUN_SDK_LAST_HTTP_CODE == 200 | 1 = ALIYUN_SDK_LAST_HTTP_CODE != 200 35 | aliapi_rpc [<--key> ...] 36 | ``` 37 | 38 | `AliyunOpenApiSDK.sh` 可以作为脚本使用,脚本第一个参数为 `--rpc`,剩余参数为 `aliapi_rpc` 可接受参数。作为脚本使用时,`AliAccessKeyId` 和 `AliAccessKeySecret` 变量需要 `export`。 39 | 40 | **示例:** 41 | 42 | ```bash 43 | #!/usr/bin/env bash 44 | 45 | # 设置 AliAccessKeyId 和 AliAccessKeySecret 46 | AliAccessKeyId="" 47 | AliAccessKeySecret="" 48 | 49 | # 导入 SDK 50 | source AliyunOpenApiSDK.sh 51 | 52 | get_show_size() { 53 | echo 50 54 | } 55 | 56 | # 获取 SSL 证书列表:https://help.aliyun.com/document_detail/126511.html 57 | # 如果值以 () 结尾,那么 SDK 会假设它是一个函数,获取值时会判断函数是否存在并执行。 58 | # 如果不存在则使用原始值,所以这里 ShowSize 的值是 50。 59 | aliapi_rpc GET cas.aliyuncs.com 2018-07-13 DescribeUserCertificateList --CurrentPage 1 --ShowSize "get_show_size()" 60 | # 如果 HTTP 状态码是 200,那么返回代码是 0,否则返回代码为 1。 61 | # 使用 ALIYUN_SDK_LAST_HTTP_CODE 变量可以获取最后一次调用的 HTTP 状态码。 62 | if [[ $? -eq 0 ]]; then 63 | # 执行成功 64 | else 65 | # 执行失败 66 | fi 67 | ``` 68 | 69 | 更多示例请参考 [examples](/examples) 下的文件 70 | 71 | 如果你有好的示例,欢迎提交 [PR](https://github.com/Hill-98/aliyun-openapi-bash-sdk/pulls)。 72 | -------------------------------------------------------------------------------- /examples/UpdateSSLCert.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 使用的 OpenAPI 4 | # CAS: https://help.aliyun.com/document_detail/126507.html 5 | # CDN:https://help.aliyun.com/document_detail/106661.html 6 | 7 | # 可配合 acme.sh 使用的 renewHook 脚本:自动将新证书上传至阿里云并更新对应 CDN 域名,然后删除对应域名的旧证书。 8 | # 每次 API 执行都会检测是否失败,如果失败,会中断脚本执行并返回自定义错误代码。 9 | 10 | AliAccessKeyId="" 11 | AliAccessKeySecret="" 12 | # shellcheck source=AliyunOpenApiSDK.sh 13 | source ../AliyunOpenApiSDK.sh 14 | 15 | # acme.sh 执行 renewHook 时导出的环境变量列表 16 | ACME_ENV_LIST=( 17 | "CERT_PATH" 18 | "CERT_KEY_PATH" 19 | "CA_CERT_PATH" 20 | "CERT_FULLCHAIN_PATH" 21 | "Le_Domain" 22 | ) 23 | # 检查环境变量是否存在 24 | for value in "${ACME_ENV_LIST[@]}" ; do 25 | [[ -v "$value" ]] || exit 1 26 | done 27 | unset value 28 | 29 | # 获取证书自定义函数 30 | get_cert() { 31 | # 使用 sed 删除掉证书文件的空行 32 | sed -e "/^$/d" "$CERT_FULLCHAIN_PATH" 33 | } 34 | # 获取密钥自定义函数 35 | get_key() { 36 | cat "$CERT_KEY_PATH" 37 | } 38 | 39 | # shellcheck disable=SC2154 40 | DOMAIN=$Le_Domain 41 | # 证书名称 (替换域名的 . 为 _,以符合阿里云证书名称规范) 42 | CERT_NAME="${DOMAIN//./_}-$(date +%s)" 43 | # 需要更新证书的 CDN 域名列表 44 | DOMAIN_LIST=( 45 | "example.example.com" 46 | ) 47 | 48 | # 获取证书列表 49 | result=$(aliapi_rpc GET cas.aliyuncs.com 2018-07-13 DescribeUserCertificateList --CurrentPage 1 --ShowSize 50) || exit 101 50 | # 使用 jq 处理返回的 JSON 数据并提取出匹配当前证书域名的证书列表的 ID,用于稍后的删除旧证书操作。 51 | cert_list=$(jq -cr ".CertificateList|map(select(.common == \"$DOMAIN\"))|map(.id)|.[]" <<< "$result") 52 | 53 | # 上传新的证书 54 | aliapi_rpc GET cas.aliyuncs.com 2018-07-13 CreateUserCertificate --Cert "get_cert()" --Key "get_key()" --Name "$CERT_NAME" || exit 102 55 | 56 | # 设置 CDN 域名列表使用新的证书 57 | for _domain in "${DOMAIN_LIST[@]}"; do 58 | aliapi_rpc GET cdn.aliyuncs.com 2018-05-10 SetDomainServerCertificate --DomainName "$_domain" --ServerCertificateStatus on --CertName "$CERT_NAME" --CertType cas || exit 103 59 | done 60 | unset _domain 61 | 62 | # 删除旧的证书 63 | for _id in ${cert_list}; do 64 | aliapi_rpc GET cas.aliyuncs.com 2018-07-13 DeleteUserCertificate --CertId "$_id" || exit 104 65 | done 66 | unset _id 67 | -------------------------------------------------------------------------------- /test/test.bats.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | # shellcheck shell=bash disable=SC2154 3 | 4 | bats_require_minimum_version "1.5.0" 5 | 6 | load "test_helper/bats-assert/load.bash" 7 | load "test_helper/bats-support/load.bash" 8 | 9 | setup() { 10 | # shellcheck disable=SC1091 11 | [[ -f .env.test ]] && source .env.test 12 | source AliyunOpenApiSDK.sh 13 | } 14 | 15 | skip_no_aliaccess() { 16 | if [[ ! -v AliAccessKeyId || ! -v AliAccessKeySecret ]]; then 17 | skip "'AliAccessKeyId' or 'AliAccessKeySecret' environment variable not found" 18 | fi 19 | } 20 | 21 | test_signature_nonce() { #@test 22 | nonceA=$(_aliapi_signature_nonce) 23 | nonceB=$(_aliapi_signature_nonce) 24 | assert_not_equal "$nonceA" "$nonceB" 25 | } 26 | 27 | test_signature_rpc() { #@test 28 | assert_equal "$(_aliapi_signature_rpc GET "key=value&foo=bar")" "NcrN6odhMq2fD7LEpbT0A7K3TJg=" 29 | } 30 | 31 | test_timestamp_rpc() { #@test 32 | run -0 _aliapi_timestamp_rpc 33 | assert_output --regexp "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T(0[0-9]|[1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](Z|\+00:00)$" 34 | } 35 | 36 | test_urlencode() { #@test 37 | assert_equal "$(_aliapi_urlencode "/foo &bar#")" "%2Ffoo%20%26bar%23" 38 | assert_equal "$(_aliapi_urlencode "中文测试")" "%E4%B8%AD%E6%96%87%E6%B5%8B%E8%AF%95" 39 | assert_equal "$(_aliapi_urlencode "$(echo -e "new\nline\ntest")")" "new%0Aline%0Atest" 40 | } 41 | 42 | test_check_vars() { #@test 43 | skip_no_aliaccess 44 | 45 | _AliAccessKeyId=$AliAccessKeyId 46 | _AliAccessKeySecret=$AliAccessKeySecret 47 | unset AliAccessKeyId AliAccessKeySecret 48 | 49 | run -3 _aliapi_check_vars 50 | assert_output "Aliyun OpenAPI SDK: 'AliAccessKeyId' or 'AliAccessKeySecret' environment variable not found" 51 | 52 | AliAccessKeyId=$_AliAccessKeyId 53 | AliAccessKeySecret=$_AliAccessKeySecret 54 | 55 | _aliapi_check_vars 56 | } 57 | 58 | getQueryType() { 59 | echo MetaTag 60 | } 61 | 62 | test_rpc_api() { #@test 63 | skip_no_aliaccess 64 | 65 | run -2 aliapi_rpc GET api.test 0 66 | assert_output "aliapi_rpc: not enough parameters" 67 | 68 | run -2 aliapi_rpc GET api.test 0 api unknown 69 | assert_output "aliapi_rpc: 'unknown' is unknown parameter" 70 | 71 | run -2 aliapi_rpc GET api.test 0 api --unknown 72 | assert_output "aliapi_rpc: '--unknown' has no value" 73 | 74 | run -0 aliapi_rpc GET sts.aliyuncs.com 2015-04-01 GetCallerIdentity 75 | assert_output --partial "user/aliyun-openapi-shell-sdk-test" 76 | 77 | run -0 aliapi_rpc GET tag.aliyuncs.com 2018-08-28 ListTagKeys --RegionId cn-hangzhou --QueryType "getQueryType()" 78 | assert_output --partial '"Key":"openapi-shell-sdk-test"' 79 | } 80 | 81 | test_cli() { #@test 82 | skip_no_aliaccess 83 | 84 | export AliAccessKeyId AliAccessKeySecret 85 | 86 | run -2 ./AliyunOpenApiSDK.sh 87 | assert_output "AliyunOpenApiSDK.sh <--rpc> [<--key> ...]" 88 | 89 | run -2 ./AliyunOpenApiSDK.sh --cpr 90 | assert_output "Aliyun OpenAPI SDK: '--cpr' is unknown parameter" 91 | 92 | run -0 ./AliyunOpenApiSDK.sh --rpc GET sts.aliyuncs.com 2015-04-01 GetCallerIdentity 93 | assert_output --partial "user/aliyun-openapi-shell-sdk-test" 94 | 95 | run -0 ./AliyunOpenApiSDK.sh --rpc GET tag.aliyuncs.com 2018-08-28 ListTagKeys --RegionId cn-hangzhou --QueryType MetaTag 96 | assert_output --partial '"Key":"openapi-shell-sdk-test"' 97 | } 98 | 99 | test_command_not_found() { #@test 100 | run -127 /bin/bash -c 'PATH="" ./AliyunOpenApiSDK.sh' 101 | assert_output --regexp "^Aliyun OpenAPI SDK: [A-Za-z0-9_-]+ command not found$" 102 | } 103 | --------------------------------------------------------------------------------