shell脚本

1.case语句

可以实现switch case的逻辑

case $server_vendor in
  "HP"|"Hewlett-Packard")
    install_rpm "HP"
    hp_server_hardware_health_check
    ;;
  *)
    install_rpm "Other"
    other_server_hardware_health_check
    ;;
  esac

2.函数的参数传递

2.1 函数的定义

函数的第一个入参$1

function install_rpm() {
  case $1 in
  "HP")
    if [ ! -f ${RPM_BACKAGE_STORAGE_LOCATION}/${HP_SSACLI_COMMAND_RPM_NAME} ]; then
        timeout 60s wget "${DOWNLOAD_BASE_URL}/${HP_SSACLI_COMMAND_RPM_NAME}" -O ${RPM_BACKAGE_STORAGE_LOCATION}/${HP_SSACLI_COMMAND_RPM_NAME} &>/dev/null
    fi

    if [ ! -f ${RPM_BACKAGE_STORAGE_LOCATION}/${HP_SSACLI_COMMAND_RPM_NAME2} ]; then
        timeout 60s wget "${DOWNLOAD_BASE_URL}/${HP_SSACLI_COMMAND_RPM_NAME2}" -O ${RPM_BACKAGE_STORAGE_LOCATION}/${HP_SSACLI_COMMAND_RPM_NAME2} &>/dev/null
    fi

    cd ${RPM_BACKAGE_STORAGE_LOCATION}
    rpm -Uvh "${RPM_BACKAGE_STORAGE_LOCATION}/${HP_SSACLI_COMMAND_RPM_NAME}" &>/dev/null
    rpm -Uvh "${RPM_BACKAGE_STORAGE_LOCATION}/${HP_SSACLI_COMMAND_RPM_NAME2}" &>/dev/null
    ;;
  "Other")
    if [ ! -f ${RPM_BACKAGE_STORAGE_LOCATION}/${LIB_UTILS_RPM_NAME} ]; then
      timeout 60s wget "${DOWNLOAD_BASE_URL}/${LIB_UTILS_RPM_NAME}" -O ${RPM_BACKAGE_STORAGE_LOCATION}/${LIB_UTILS_RPM_NAME} &>/dev/null
    fi
    if [ ! -f ${RPM_BACKAGE_STORAGE_LOCATION}/${OTHER_MEGACLI_COMMAND_RPM_NAME} ]; then
      timeout 60s wget "${DOWNLOAD_BASE_URL}/${OTHER_MEGACLI_COMMAND_RPM_NAME}" -O ${RPM_BACKAGE_STORAGE_LOCATION}/${OTHER_MEGACLI_COMMAND_RPM_NAME} &>/dev/null
    fi

    cd ${RPM_BACKAGE_STORAGE_LOCATION}
    rpm -Uvh "${RPM_BACKAGE_STORAGE_LOCATION}/${LIB_UTILS_RPM_NAME}" &>/dev/null
    rpm -Uvh "${RPM_BACKAGE_STORAGE_LOCATION}/${OTHER_MEGACLI_COMMAND_RPM_NAME}" &>/dev/null
    ln -s /opt/MegaRAID/MegaCli/MegaCli64 /bin/MegaCli64 2>/dev/null
    ln -s /opt/MegaRAID/MegaCli/MegaCli64 /sbin/MegaCli64 2>/dev/null
    ;;
  *)
    :
    ;;
  esac
}

2.2 函数的调用

install_rpm "HP"

3.shell脚本输出json字符串

#!/bin/bash

# 定义一个关联数组
declare -A data
data["name"]="John"
data["age"]=30
data["city"]="New York"

# 将关联数组转换为json字符串
json=$(declare -p data)
json=${json#*=}

# 输出json字符串
echo $json

结果打印

{"name":"John","city":"New York","age":30}

4.脚本优化

4.1 数组定义及遍历

LOG_ARRAY=("access.log" "error.log")

# 遍历
for log in "${LOG_ARRAY[@]}"; do
    logrotate "$log" # 参数传递时建议双引号标记起来
done

4.2 函数定义传参

function logrotate() {
  local log_file="$1" # 接受第一个参数赋值给变量log_file,也一定要用双""标记起来
}

4.3 计数器相加

((count++)) # 此种写法比使用expr 进行运算,性能更高,更直观

4.4 数字比较判断

if ((current_size > MAX_SIZE)); then # 采用(())进行比较运算,更符合语义,且不用写$符号,不建议使用if [ $current_size -gt $MAX_SIZE ]
    echo 1
  fi

其他比较判断

if [[ ! -f "${LOG_DIRECTORY}/${log_file}" ]]; then # 添加了双引号来包裹文件路径,以防止由于文件名或路径中的空格等特殊字符导致的问题。
    return
  fi

4.5 命令执行结果放另一个语句里,加上“

/bin/kill -USR1 "$(cat "$PID_FILE")" 2>/dev/null #cat "$PID_FILE" 的写法,及最后外部包的"

4.6 函数的参数传递

建议用""引起来,即使是变量

logrotate "$log"

4.7 字符串截取

字符串截取.前面的内容

local log_file="access.log"
local log_file_prefix="${log_file%.*}" # access

4.8 常量定义

建议放开头,并且大写标注

# ---------------------------------------------------------------------
LOG_DIRECTORY="/export/servers/nginx/logs"     # 日志文件目录
MAX_SIZE=500                                   # 日志文件的最大大小,单位为MB
LOG_ARRAY=("access.log" "error.log")           # 要操作的日志集合
PID_FILE="/export/servers/nginx/run/nginx.pid" # nginx的PID
# ---------------------------------------------------------------------

4.9 获取文件大小

local current_size=$(stat -c %s "$log_path") # 获取的单位是B

4.10 文件路径动态拼接的提前赋值给变量

local log_path="${LOG_DIRECTORY}/${log_file}" # 后续操作直接操作变量,减少性能损耗

4.11 移动文件

mv -f # 添加-f的覆盖逻辑,防止被阻塞掉
posted @ 2023-09-11 13:59  SpecialSpeculator  阅读(7)  评论(0编辑  收藏  举报