不理解此 bash 脚本中的某些命令

Don't understand certain commands in this bash script

我受命修改此 bash 脚本,但此脚本中有些语法我不太明白。

我在研究和研究了一些bash后了解了大多数。我对在这里发布整个脚本感到很遗憾,但我不想向您隐藏任何信息,以免让您更难回答我的问题。

基本上我在理解下面脚本中的 bash 命令方面存在差距。

  1. if [[ ${#} -eq 3 ]]; then - 这里的$#是什么?什么是 [[]]
  2. eval HOSTNAME_PORT=$$ENV eval config_mapping_values=$$MAPPING - 这里有 2 $?斜杠怎么了
  3. IFS=',' read -a mapping_value_array <<< "$mapping_values_param"
  4. "${!mapping_value_array[@]}" - 循环开头的@符号是什么?
  5. type_name=$(echo $map_value_item | cut -d":" -f1)- 为什么括号内外都要用$符号?

完整脚本:

#!/bin/sh

insert_mapping()
{
  mapping_name_param=
  mapping_values_param=
  echo "Calling insert mapping: name: $mapping_name_param values: $mapping_values_param "

  IFS=',' read -a mapping_value_array <<< "$mapping_values_param"

  for index in "${!mapping_value_array[@]}"
  do
    map_value_item=${mapping_value_array[index]}

    if [[ $index -eq 0 ]];then
            echo "Calling Curl Command: curl -XPUT "$HOSTNAME_PORT/$mapping_name_param" -d @$map_value_item"
        curl -XPUT "$HOSTNAME_PORT/$mapping_name_param" -d @$map_value_item
    else
        type_name=$(echo $map_value_item | cut -d":" -f1)
        type_file=$(echo $map_value_item | cut -d":" -f2)
            echo "Calling Curl Command: curl -XPUT "$HOSTNAME_PORT/$mapping_name_param/$type_name/_mapping" -d @$type_file"
        curl -XPUT "$HOSTNAME_PORT/$mapping_name_param/$type_name/_mapping" -d @$type_file
    fi
  done
}

delete_mapping()
{
  mapping_name_param=
  echo "Calling Curl Command: curl -XDELETE "$HOSTNAME_PORT/$mapping_name_param""
  curl -XDELETE "$HOSTNAME_PORT/$mapping_name_param"
}

#
# MAIN METHOD
#
source ./configure_es_mapping_util.cfg

if [[ ${#} -eq 3 ]]; then
     export ENV=
     export ACTION=
     export MAPPING=
     echo "ENV: $ENV ACTION $ACTION MAPPING $MAPPING"

     eval HOSTNAME_PORT=$$ENV
     eval config_mapping_values=$$MAPPING

     if [[ "$ACTION" == "insert" || "$ACTION" == "INSERT" ]]; then
       if [[ "$MAPPING" == "all" ]]; then
          IFS=',' read -a all_mappings_array <<< "$all_mappings"
          for i in "${all_mappings_array[@]}"
          do
              eval config_mapping_values=$$i
              insert_mapping $i $config_mapping_values
          done
       else
         insert_mapping $MAPPING $config_mapping_values
       fi
     elif [[ "$ACTION" == "delete" || "$ACTION" == "DELETE" ]]; then
        echo "Calling delete: $ACTION"
       if [[ "$MAPPING" == "all" ]]; then
          IFS=',' read -a all_mappings_array <<< "$all_mappings"
          for i in "${all_mappings_array[@]}"
          do
              delete_mapping $i
          done
       else
         delete_mapping $MAPPING
       fi
    else
        echo "unknown action"
    fi
else
    echo "Invalid Arguments: Provide Env(ITE, QA, UAT, PROD) Action(INSERT, DELETE) Mapping(icrd_alerts)"
    exit 1
fi
if [[ ${#} -eq 3 ]]; then

此语句测试position parameters个数(例如命令行参数个数)是否为3.

eval HOSTNAME_PORT=$$ENV eval config_mapping_values=$$MAPPING

eval 的参数被读取并连接成一个命令。语法 $$ 是一个 indirect reference。此处使用 eval 会导致 HOSTNAME_PORT 被设置为变量 $(whatever $ENV is) 的值。因此,如果 $ENV 包含 "host1"、HOSTNAME_PORT=$host1。这同样适用于 config_mapping_values=$$MAPPING

IFS=',' read -a mapping_value_array <<< "$mapping_values_param"

IFS 是 Bash Internal Field Separator(默认是 $' \t\n'(space tab 换行符))控制 word-splitting 如何发生.它导致 "$mapping_values_param" 中的单词在 , 上被拆分,结果读入数组 mapping_value_array.

"${!mapping_value_array[@]}" in the loop beginning I see this.

associative array 的键使用感叹号访问。在循环的开始,它只是 returns 一个要迭代的 key 值列表。然而,由于数组 mapping_value_array 是一个常规的 indexed 数组(参见上面的 read -a mapping_value_array),结果只是数组中每个元素的索引(例如 0 1 2 3...) .

type_name=$(echo $map_value_item | cut -d":" -f1)

变量type_name被赋值为command substitution的结果(例如echo $map_value_item | cut -d":" -f1的结果)。