简体   繁体   English

如何使这个 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" "$1")

#check for condition
  if [ "$status" = 200 ]; then
    echo "Running successfully! $2 Status code: $status"
  else
    echo "Error! $2 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 "$3" -X POST $1)

#check for condition
  if [ "$status" = 200 ]; then
    echo "Running successfully! $2 Status code: $status"
  else
    echo "Error! $2 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"}'

Basically first half of the code has GET request urls and second half have POST request urls with some data.基本上代码的前半部分有 GET 请求 url,后半部分有 POST 请求 url 和一些数据。 I want to know how can this script be made less repetitive.我想知道如何才能减少这个脚本的重复性。

How to make 2 if statements as one?如何将 2 个if 语句合二为一? Also is it possible to combine the three lines (14-16) that are "api_get https://cms.abc.co/api/method/contentready_edu_cms.api."也可以将“api_get https://cms.abc.co/api/method/contentready_edu_cms.api”这三行 (14-16) 组合起来。 because the only different thing is api_1, api_2, api_3 and api names after that ("api_1", "api_2", "api_3").因为唯一不同的是 api_1、api_2、api_3 和 api 名称(“api_1”、“api_2”、“api_3”)。 If not the urls, can we at least keep them all under one api_get function?如果不是网址,我们至少可以将它们全部放在一个api_get function 下吗?

How to make 2 if statements as one?如何将 2 个 if 语句合二为一?

?? ?? I don't see such a thing in your code我在你的代码中没有看到这样的东西

is it possible to combine the three lines (14-16)是否可以结合三行(14-16)

Yes:是的:

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

For the POST calls, consider an array mapping the api name to the data:对于 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

The two functions can be combined: just need to pass the HTTP command as a parameter.这两个功能可以结合使用:只需将HTTP命令作为参数传递即可。 Can do the URL construction in there too.也可以在那里进行 URL 构造。

api() {
  local cmd=$1 api_name=$2
  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 "$4"
      )
      ;;
    *) 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
}

Then然后

api_root=...

api GET "api_1"

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

Another advantage here is you don't have to hardcode the token in two places.这里的另一个优点是您不必在两个地方对令牌进行硬编码。

I assume that "api_1, api_2, etc" is not always consecutive, so a simple approach is to create separated lists with the URLs and the data then pass that to the script.我假设“api_1、api_2 等”并不总是连续的,因此一种简单的方法是使用 URL 和数据创建单独的列表,然后将其传递给脚本。 If you add the below section to your current script you can run it like this如果您将以下部分添加到当前脚本中,您可以像这样运行它

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

method="${1}"
file="${2}"

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

get_list.txt: 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: 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"}'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM