Shell脚本适用于win10,而不适用于Linux

时间:2018-01-12 08:45:48

标签: bash shell

我正在使用来自Link的akamai清除脚本并进行了一些修改,因此变量存在于文件本身中。此代码成功运行并清除win10上的对象,但是当我在linux上运行它时它不会清除,它也会在控制台中显示相同的文本。我不熟悉shell脚本,任何想法有什么不对吗?

## Functions ------------------------------------------------------------------

function _get_property {
  [ "$#" -lt 2 ] && return 1
  local RC=$1
  local PROP=$2
  local value=$(cat ${RC} | sed "/^\s*#/d;s/\s*#[^\"']*$//" | grep ${PROP} | tail -n 1 | cut -d '=' -f2- )
  if [ -z "${value}" ]; then
    return 1
  else
    echo ${value}
    return 0
  fi
}

function get_properties {
  local file="${1}"

  declare -A aka_props

  aka_props[client_secret]=$( _get_property "${file}" client_secret )
  [ -z "${aka_props[client_secret]}" ] && { >&2 echo "ERROR: Please, set variable client_secret in file ${file}!!!"; exit 1; }
  aka_props[client_token]=$( _get_property "${file}" client_token )
  [ -z "${aka_props[client_token]}" ] && { >&2 echo "ERROR: Please, set variable client_token in file ${file}!!!"; exit 1; }
  aka_props[access_token]=$( _get_property "${file}" access_token )
  [ -z "${aka_props[access_token]}" ] && { >&2 echo "ERROR: Please, set variable access_token in file ${file}!!!"; exit 1; }
  aka_props[host]=$( _get_property "${file}" host )
  [ -z "${aka_props[host]}" ] && { >&2 echo "ERROR: Please, set variable host in file ${file}!!!"; exit 1; }

  aka_props[network]=$( _get_property "${file}" network )
  [ -z "${aka_props[network]}" ] && aka_props[network]="staging"
  aka_props[action]=$( _get_property "${file}" action )
  [ -z "${aka_props[action]}" ] && aka_props[network]="invalidate"
  aka_props[type]=$( _get_property "${file}" type )
  [ -z "${aka_props[type]}" ] && aka_props[network]="type"

  declare -p aka_props | cut -d '=' -f2-

  return 0
}

declare -A AKA_PROPS
AKA_PROPS[client_secret]=<client_secret>
AKA_PROPS[client_token]=<client_token>
AKA_PROPS[access_token]=<access_token>
AKA_PROPS[host]=<host>
AKA_PROPS[network]="production"
AKA_PROPS[action]="delete"
AKA_PROPS[type]="url"

function mk_nonce {
  local s=$1
  if [ -z ${s} ]; then s=$( date -u +'%Y%m%dT%H:%M:%S%z' ); fi
  echo -n "${s}" | md5sum | cut -d ' ' -f1 | sed 's/.\{4\}/&-/g' | sed 's/.$//'
}

function base64_hmac_sha256 {
  [ "$#" -lt 2 ] && return 1
  local key=$1
  local value=$2

  echo -ne "${value}"| openssl sha256 -binary -hmac "${key}" | openssl base64
}

function base64_sha256 {
   [ "$#" -lt 1 ] && return 1
   local value=$1

   echo -ne "${value}" | openssl dgst -binary -sha256 | openssl base64
}

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};"  
  #echo -n "EG1-HMAC-SHA256 client_token=${aka_props[client_token]};access_token=${aka_props[access_token]};timestamp=${timestamp};nonce=${nonce};"
}

function sign_data {
  [ "$#" -lt 2 ] && return 1
  local key=$1
  local -n data_to_sign=$2

  #local data="${data_to_sign[method]}\t${data_to_sign[scheme]}\t${data_to_sign[host]}\t${data_to_sign[request_uri]}\t${data_to_sign[canonical_headers]}\t${data_to_sign[hash_content]}\t${data_to_sign[auth_header]}"
  local data="${data_to_sign[method]}\t${data_to_sign[scheme]}\t${data_to_sign[host]}\t${data_to_sign[request_uri]}\t\t${data_to_sign[hash_content]}\t${data_to_sign[auth_header]}"
  base64_hmac_sha256 "${key}" "${data}"
}

function mk_body {
  local type="${1}"
  local objects="${2}"
  local domain="${3}"

  local arr_objects
  local objs

  IFS=',' read -r -a arr_objects <<< "${objects}"
  for i in ${!arr_objects[@]}
  do
    local tmp=$( echo ${arr_objects[i]} | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's,/,\\/,g' )
    if [ "${type}" == "cpcode" ]; then
      objs="${objs},${tmp}"
    else
      objs="${objs},\"${tmp}\""
    fi
  done

  objs=$( echo "${objs}" | sed 's/^,//' )

  if [ "${type}" == "url" ]; then
    echo "{\"hostname\":\"${domain}\",\"objects\":[${objs}]}"
  else
    echo "{\"objects\":[${objs}]}"
  fi
}


## Options --------------------------------------------------------------------

P_NAME=${0##*\/}

#CONF=./.akarc
#[ ! -f ${CONF} ] && CONF=./.akarc
#[ ! -f ${CONF} ] && { >&2 echo "ERROR: configuration file not found (~/.akarc or /etc/.akarc)"; exit 1; }

#declare -A AKA_PROPS=$( get_properties "${CONF}" );

usage() {
cat << EOF
usage: ${P_NAME} [OPTIONS] -o <obj1[,obj2,obj3,...]>

Purge the Akamai cache via CCU REST API v3.

REMARKS
  Please create a config file in ~/.akarc or /etc/.akarc

PARAMETERS:
    -o | --objects        List of objects to purge (with comma separated values)


OPTIONS:
    -t | --type           Type of objects
                        Possible values: url, cpcode or tag
                        Default: ${AKA_PROPS[type]}

    -d | --domain         Domain site (es. your.domain.com).
                      To use with type=url

    -a | --action         The desired action to manage the cache
                        Possible values: invalidate or delete
                        Default: ${AKA_PROPS[action]}

    -n | --network        The network on which you want to invalidate or delete content
                        Possible values: staging or production
                        Default: ${AKA_PROPS[network]}

-h | --help           Show this message
-v | --version        Show version


CONFIG FILE:

  In the config file the following values have to been declared:
    client_secret = <your client secret>
    client_token = <your client token>
    access_token = <your access token>
    host = <your akamai host>

  There is the possibility to set the default values:
    network = <staging | production>
    action  = <invalidate | delete>
    type    = <url | cpcode | tag>

  If no values are declared the default ones are:
    network = staging
    action  = invalidate
    type    = url
EOF
}

ARGS=$( getopt -o "d:t:o:a:n:hv" -l "domain:,type:,objects:,action:,network:,help,version" -n "$0" -- "$@" )
eval set -- "$ARGS"

VERSION=0.2

NETWORK=${AKA_PROPS[network]}
ACTION=${AKA_PROPS[action]}
TYPE=${AKA_PROPS[type]}

while true; do
  case "$1" in
    -d | --domain )
      DOMAIN=${2}
      shift 2
    ;;
    -t | --type )
      TYPE=${2}
      shift 2
    ;;
    -o | --objects )
      OBJECTS=${2}
      shift 2
    ;;
    -a | --action )
      ACTION=${2}
      shift 2
    ;;
    -n | --network )
      NETWORK=${2}
      shift 2
    ;;
    -h | --help )
      usage
      exit 0
    ;;
    -v | --version )
      echo $0 version: $VERSION
      exit 0
    ;;
    -- )
      shift
      break
    ;;
    * )
      >&2 echo "Internal error!"
      exit 1
    ;;
  esac
done

## Main -----------------------------------------------------------------------

[ -z "${TYPE}" ] || [ -z "${OBJECTS}" ] && { usage; exit 1; }
[ "${TYPE}" == "url" ] && [ -z "${DOMAIN}" ] && { usage; exit 1; }

[ "${TYPE}" != "url" ] && [ ! -z "${DOMAIN}" ] && { echo "WARNING: type is different of url then -d,--domain will be ignored ..."; }

[ "${TYPE}" != "url" ] && [ "${TYPE}" != "cpcode" ] && [ "${TYPE}" != "tag" ] && { >&2 echo "ERROR: Possible value of OBJECT TYPE is url, cpcode or tag"; exit 1; }
[ "${NETWORK}" != "staging" ] && [ "${NETWORK}" != "production" ] && { >&2 echo "ERROR: Possible value of NETWORK is staging or production"; exit 1; }
[ "${ACTION}" != "invalidate" ] && [ "${ACTION}" != "delete" ] && { >&2 echo "ERROR: Possible value of ACTION is invalidate or delete"; exit 1; }

BODY=$( mk_body "${TYPE}" "${OBJECTS}" "${DOMAIN}" )
[ $(echo -ne "${BODY}" | wc -c ) -gt 131072 ] && { >&2 echo "ERROR: The body size is greater than 131072!!!" exit 1; }

TIMESTAMP=$( date -u +'%Y%m%dT%H:%M:%S%z' )
NONCE=$( mk_nonce ${TIMESTAMP} )
SIGN_KEY=$( base64_hmac_sha256 ${AKA_PROPS[client_secret]} ${TIMESTAMP} )
AUTH_HEADER=$( mk_auth_header AKA_PROPS ${TIMESTAMP} ${NONCE} )

declare -A DATA_TO_SIGN=( [method]="POST"
                      [scheme]="https"
                      [host]="${AKA_PROPS[host]}"
                      [request_uri]="/ccu/v3/${ACTION}/${TYPE}/${NETWORK}"
                      [hash_content]=$( base64_sha256 "${BODY}" )
                      [auth_header]=$( mk_auth_header AKA_PROPS ${TIMESTAMP} ${NONCE}) )


SIGNED_DATA=$( sign_data "${SIGN_KEY}" DATA_TO_SIGN )
SIGNED_AUTH_HEADER="Authorization: ${AUTH_HEADER}signature=${SIGNED_DATA}"

H_JSON="Content-Type: application/json"

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]}\" | bash -x | jq .

   exit 0

2 个答案:

答案 0 :(得分:0)

AKA_PROPS[client_secret]=<client_secret>

希望您用Linux中的实际值替换<client_secret></>用于重定向。除此之外,我会在下面提出建议。

  • 将一个shebang(#!/bin/bash)添加到文件顶部
  • 然后运行dos2unix script_name
  • 最后运行脚本。

答案 1 :(得分:0)

$ {AKA_PROPS [network]}等关联数组可用于bash 4.0或更新版本,因此首先要做的是检查Linux上的bash版本与Window $上的版本。

bash --version
GNU bash, version 4.3.42(1)-release (x86_64-suse-linux-gnu)

另一件好事是在原始脚本的第119行之后添加更改。确保正确引用值,并且脚本中存在.akarc文件中的所有值。

#declare -A AKA_PROPS=$( get_properties "${CONF}" );
declare -A AKA_PROPS
AKA_PROPS[client_secret]=<client_secret>
AKA_PROPS[client_token]=<client_token>
AKA_PROPS[access_token]=<access_token>
AKA_PROPS[host]=<host>
AKA_PROPS[network]="production"
AKA_PROPS[action]="delete"
AKA_PROPS[type]="url"

您可以使用-h选项进行测试,因为AKA_PROPS值将显示在帮助文本中(例如,默认值:$ {AKA_PROPS [type]})。