如何使这个 bash 脚本干净并减少重复?

How to make this bash script clean and less repetitive?

#declaring function for GET request
api_get() {
  status=$(curl -o /dev/null -s -w "%{http_code}\n" -H "Authorization: token 123abc" "")

#check for condition
  if [ "$status" = 200 ]; then
    echo "Running successfully!  Status code: $status"
  else
    echo "Error!  Status code: $status"
  fi
}

#running the function for each URL
api_get https://cms.abc.co/api/method/contentready_edu_cms.api.api_1 "api_1"
api_get https://cms.abc.co/api/method/contentready_edu_cms.api.api_2 "api_2"
api_get https://cms.abc.co/api/method/contentready_edu_cms.api.api_3 "api_3"


#declaring function for POST request
api_post() {
  status=$(curl -o /dev/null -s -w "%{http_code}\n" -H "Authorization: token 123abc" -H "Content-Type: application/json" -d "" -X POST )

#check for condition
  if [ "$status" = 200 ]; then
    echo "Running successfully!  Status code: $status"
  else
    echo "Error!  Status code: $status"
  fi
}

#running the function for each URL
api_post https://cms.abc.co/api/method/contentready_edu_cms.api.api_1 "api_1" '{"some":"data1"}'
api_post https://cms.abc.co/api/method/contentready_edu_cms.api.api_2 "api_2" '{"some":"data2"}'
api_post https://cms.abc.co/api/method/contentready_edu_cms.api.api_3 "api_3" '{"some":"data3"}'

基本上代码的前半部分有 GET 请求 url,后半部分有 POST 带有一些数据的请求 url。我想知道如何让这个脚本不那么重复。

如何将 2 个 if 语句 合并为一个?也可以将三行 (14-16) 组合起来,即“api_get https://cms.abc.co/api/method/contentready_edu_cms.api." 因为唯一不同的是 api_1、api_2、api_3和 api 之后的名称(“api_1”、“api_2”、“api_3”)。如果不是 url,我们至少可以将它们都放在一个 api_get函数?

How to make 2 if statements as one?

??我在你的代码中没有看到这样的东西

is it possible to combine the three lines (14-16)

是:

api_root=https://cms.abc.co/api/method/contentready_edu_cms.api

for api in api_{1,2,3}; do
    api_get "${api_root}.${api}" "$api"
done

对于 POST 调用,考虑将 api 名称映射到数据的数组:

declare -A data=(
    [api_1]='{"some":"data1"}'
    [api_2]='{"some":"data2"}'
    [api_3]='{"some":"data3"}'
)

for api in "${!data[@]}"; do
    api_post "${api_root}.${api}" "$api" "${data[$api]}"
done

这两个功能可以结合起来:只需要将HTTP命令作为参数传递。 也可以在那里做 URL 构造。

api() {
  local cmd= api_name=
  local url=${api_root}.${api_name}

  local curl_opts=(
    -o /dev/null
    -s
    -w "%{http_code}\n"
    -H "Authorization: token 123abc"
  )

  case $cmd in
    GET) : ;;
    POST) 
      curl_opts+=(
        -X POST
        -H "Content-Type: application/json"
        -d ""
      )
      ;;
    *) echo "HTTP $cmd not implemented" >&1; return 1 ;;
  esac

  local status=$(curl "${curl_opts[@]}" "$url")

  #check for condition
  if [[ $status == 200 ]]; then
    echo "Running successfully! $api_name Status code: $status"
  else
    echo "Error! $api_name Status code: $status"
  fi
}

然后

api_root=...

api GET "api_1"

api POST "api_1" "${data[api_1]}"

这里的另一个优点是您不必在两个地方对令牌进行硬编码。

我假设 "api_1、api_2、等等"=28=] 并不总是连续的,所以一个简单的方法是用 URLs 然后数据将其传递给脚本。如果您将以下部分添加到您当前的脚本中,您可以 运行 像这样

bash request.sh get get_list.txtbash request.sh post post_list.txt

method=""
file=""

case "${method}" in
    get|post);;
    *) exit 1;;
esac

[ ! -e "${file}" ] && exit 1;

OFS=$IFS
IFS=$'\n'
while read line; do
    api_url=$(echo ${line} | cut -d' ' -f1)
    # only required by post method, it will be empty if there is no data and ignored by your get function
    data=$(echo ${line} | cut -d' ' -f2)

    api_name=$(echo ${api_url} | awk -F'.' '{print $NF}')
    api_${method} "${api_url}" "${api_name}" "${data}"

done < ${file}
IFS=$OFS

名称是从URL中提取出来的,所以不需要作为参数传递

get_list.txt:

https://cms.abc.co/api/method/contentready_edu_cms.api.api_1
https://cms.abc.co/api/method/contentready_edu_cms.api.api_2
https://cms.abc.co/api/method/contentready_edu_cms.api.api_3

post_list.txt:

https://cms.abc.co/api/method/contentready_edu_cms.api.api_1 '{"some":"data1"}'
https://cms.abc.co/api/method/contentready_edu_cms.api.api_2 '{"some":"data2"}'
https://cms.abc.co/api/method/contentready_edu_cms.api.api_3 '{"some":"data3"}'