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的覆盖逻辑,防止被阻塞掉
原创:做时间的朋友