第一时间看干货文章
【就业】简历模版
一、参数处理进阶:打造专业级CLI工具
1. 高级参数解析示例
bash
#!/bin/bash
# 专业级参数处理脚本
VERSION="1.2.0"
VERBOSE=false
usage() {
cat <<EOF
脚本名称: $(basename "$0")
版本: $VERSION
用法: $0 [选项] [命令]
选项:
-h, --help 显示帮助信息
-v, --verbose 显示详细输出
-V, --version 显示版本信息
-f, --file FILE 指定输入文件
-o, --output DIR 指定输出目录
命令:
start 启动服务
stop 停止服务
restart 重启服务
EOF
}
# 使用getopt处理长选项
TEMP=$(getopt -o hvf:o:V --long help,verbose,file:,output:,version -n "$0" -- "$@")
evalset -- "$TEMP"
whiletrue; do
case"$1"in
-h|--help) usage; exit 0 ;;
-v|--verbose) VERBOSE=true; shift ;;
-f|--file) INPUT_FILE="$2"; shift 2 ;;
-o|--output) OUTPUT_DIR="$2"; shift 2 ;;
-V|--version) echo"版本: $VERSION"; exit 0 ;;
--) shift; break ;;
*) echo"内部错误!"; exit 1 ;;
esac
done
# 处理剩余的命令参数
COMMAND=${1:-}
shift
if$VERBOSE; then
echo"[DEBUG] 输入文件: ${INPUT_FILE:-未设置}"
echo"[DEBUG] 输出目录: ${OUTPUT_DIR:-未设置}"
echo"[DEBUG] 执行命令: ${COMMAND:-未设置}"
fi
case"$COMMAND"in
start) echo"启动服务..." ;;
stop) echo"停止服务..." ;;
restart) echo"重启服务..." ;;
*) echo"错误: 未知命令 '$COMMAND'"; usage; exit 1 ;;
esac
2. 参数处理方式对比
二、函数库开发:构建可重用代码
1. 创建函数库文件 (lib/utils.sh)
bash
#!/bin/bash
# 实用函数库
# 彩色输出函数
color_echo() {
local color=$1
shift
case$colorin
red) echo -e "\033[31m$*\033[0m" ;;
green) echo -e "\033[32m$*\033[0m" ;;
yellow) echo -e "\033[33m$*\033[0m" ;;
blue) echo -e "\033[34m$*\033[0m" ;;
*) echo"$*" ;;
esac
}
# 检查命令是否存在
check_cmd() {
type"$1" &> /dev/null
}
# 安全创建目录
safe_mkdir() {
if [ ! -d "$1" ]; then
mkdir -p "$1" || {
color_echo red "无法创建目录: $1"
return 1
}
fi
}
# 生成随机字符串
random_str() {
local length=${1:-8}
tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c "$length"
}
2. 在脚本中使用函数库
bash
#!/bin/bash
# 加载函数库
source"$(dirname "$0")/lib/utils.sh"
# 使用库函数
color_echo blue "开始执行系统检查..."
check_cmd "docker" || color_echo red "错误: docker未安装"
WORK_DIR="/tmp/$(random_str 10)"
safe_mkdir "$WORK_DIR" || exit 1
color_echo green "工作目录已创建: $WORK_DIR"
三、错误处理与日志记录
1. 专业级错误处理框架
bash
#!/bin/bash
# 高级错误处理示例
set -Eeuo pipefail
trap'error_handler $? $LINENO' ERR
LOG_FILE="/var/log/$(basename "$0").log"
exec 3>&1 # 保存原始stdout
exec >> "$LOG_FILE"# 重定向所有输出到日志文件
exec 2>&1 # 重定向stderr到日志文件
error_handler() {
local exit_code=$1
local line_no=$2
echo"[$(date '+%Y-%m-%d %H:%M:%S')] 错误: 脚本退出于行 $line_no,状态码 $exit_code" >&3
# 发送错误通知
send_alert "脚本错误""脚本 $(basename "$0") 在行 $line_no 失败,退出码 $exit_code"
exit"$exit_code"
}
send_alert() {
local subject=$1
local message=$2
# 实现发送邮件或HTTP通知
echo"发送警报: $subject - $message" >&3
}
# 主程序
echo"脚本启动于 $(date)" >&3
some_critical_operation
another_operation
2. 错误处理策略对比
四、并发处理:提升脚本性能
1. 并行任务处理示例
bash
#!/bin/bash
# 并行下载器
MAX_WORKERS=4
URL_LIST=(
"https://example.com/file1.zip"
"https://example.com/file2.zip"
"https://example.com/file3.zip"
"https://example.com/file4.zip"
"https://example.com/file5.zip"
)
download_file() {
local url=$1
local filename=$(basename "$url")
echo"开始下载: $filename"
if curl -s -o "$filename""$url"; then
echo"下载完成: $filename"
return 0
else
echo"下载失败: $filename"
return 1
fi
}
# 创建命名管道控制并发
fifo="/tmp/$.fifo"
mkfifo "$fifo"
exec 3<>"$fifo"
rm -f "$fifo"
# 初始化并发数
for ((i=0; i<MAX_WORKERS; i++)); do
echo >&3
done
# 并行下载
for url in"${URL_LIST[@]}"; do
read -u3 -t 1 || continue
{
download_file "$url"
echo >&3
} &
done
wait
exec 3>&-
echo"所有下载任务完成"
2. 并发技术对比
五、实战案例:系统监控与告警
1. 综合监控脚本
bash
#!/bin/bash
# 系统监控与告警脚本
CONFIG_FILE="/etc/monitor.conf"
THRESHOLDS=(
"CPU=90"
"MEM=85"
"DISK=90"
)
ALERT_EMAIL="admin@example.com"
LOG_FILE="/var/log/system_monitor.log"
# 加载配置
[ -f "$CONFIG_FILE" ] && source"$CONFIG_FILE"
# 初始化阈值
declare -A thresholds
for item in"${THRESHOLDS[@]}"; do
key=${item%=*}
value=${item#*=}
thresholds[$key]=$value
done
# 监控函数
check_cpu() {
local usage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
compare_threshold "CPU""$usage"
}
check_memory() {
local usage=$(free | awk '/Mem/{printf("%.0f"), $3/$2*100}')
compare_threshold "MEM""$usage"
}
check_disk() {
df -h | awk '$NF=="/"{print $5}' | sed 's/%//' | whileread -r usage; do
compare_threshold "DISK""$usage"
done
}
compare_threshold() {
local metric=$1
local value=$2
local threshold=${thresholds[$metric]}
if [ "$value" -ge "$threshold" ]; then
send_alert "$metric""$value""$threshold"
log_alert "$metric""$value""$threshold"
fi
}
send_alert() {
local metric=$1
local value=$2
local threshold=$3
local subject="[ALERT] ${metric}使用率过高"
local message="${metric}使用率已达${value}%,超过阈值${threshold}%"
echo"$message" | mail -s "$subject""$ALERT_EMAIL"
echo"[$(date '+%Y-%m-%d %H:%M:%S')] 警报已发送: $subject" >> "$LOG_FILE"
}
log_alert() {
echo"[$(date '+%Y-%m-%d %H:%M:%S')] ${1}警报 - 当前: ${2}%, 阈值: ${3}%" >> "$LOG_FILE"
}
# 主监控循环
whiletrue; do
check_cpu
check_memory
check_disk
sleep 300 # 5分钟间隔
done
2. 监控指标与工具对比
六、Shell脚本优化技巧
1. 性能优化对比表
2. 可读性优化示例
bash
# 差实践
for f in $(ls); doif [ -f "$f" ]; then c=$(wc -l < "$f"); if [ "$c" -gt 100 ]; thenecho"$f"; fi; fi; done
# 好实践
for file in *; do
if [ -f "$file" ]; then
line_count=$(wc -l < "$file")
if [ "$line_count" -gt 100 ]; then
echo"$file"
fi
fi
done
# 更好实践 (使用find + awk)
find . -maxdepth 1 -type f -exec awk 'FNR==101{print FILENAME; exit}' {} +
七、跨平台兼容性处理
1. 兼容性检查表
2. 兼容性检测函数
bash
#!/bin/bash
# 跨平台兼容性处理
# 检测操作系统
detect_os() {
case"$(uname -s)"in
Linux*) OS="Linux" ;;
Darwin*) OS="macOS" ;;
FreeBSD*) OS="FreeBSD" ;;
*) OS="UNKNOWN" ;;
esac
echo"检测到系统: $OS"
}
# 兼容性date命令
compatible_date() {
local format=$1
if date --version &>/dev/null; then# GNU date
date -d "$format""+%Y-%m-%d %H:%M:%S"
else# BSD date
date -j -f "%s""$format""+%Y-%m-%d %H:%M:%S"
fi
}
# 兼容性sed命令
compatible_sed() {
if sed --version &>/dev/null; then# GNU sed
sed -r "$@"
else# BSD sed
sed -E "$@"
fi
}
# 主程序
detect_os
echo"当前时间: $(compatible_date "now")"
echo"测试sed替换: $(echo "hello123" | compatible_sed 's/[0-9]+/456/')"
八、安全编程实践
1. Shell脚本安全清单
2. 安全模板脚本
bash
#!/bin/bash
# 安全脚本模板
set -euo pipefail
trap'cleanup; exit 1' INT TERM EXIT
# 安全临时文件
TEMP_FILE=$(mktemp /tmp/secure_script.XXXXXX)
cleanup() {
[ -f "$TEMP_FILE" ] && rm -f "$TEMP_FILE"
echo"清理完成"
}
# 输入验证
validate_input() {
local input=$1
# 只允许字母数字
if [[ ! "$input" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo"错误: 输入包含非法字符" >&2
exit 1
fi
}
# 安全执行外部命令
safe_exec() {
local cmd=$1
local args=("${@:2}")
# 验证命令存在
if ! type"$cmd" &>/dev/null; then
echo"错误: 命令未找到 '$cmd'" >&2
return 1
fi
# 执行命令
"$cmd""${args[@]}"
}
# 主程序
main() {
local user_input=$1
validate_input "$user_input"
echo"处理输入: $user_input" > "$TEMP_FILE"
safe_exec wc -l "$TEMP_FILE"
}
main "$@"
trap - INT TERM EXIT
cleanup
通过以上进阶实战内容,你的Shell脚本将具备专业工具的品质,能够处理复杂任务,同时保持高效和安全。
记住,优秀的Shell脚本不在于代码量多少,而在于其可靠性、可维护性和执行效率。
end
一口Linux
精彩文章合集
文章推荐
【专辑】ARM
【专辑】粉丝问答
【专辑】所有原创
【专辑】linux入门
【专辑】计算机网络
【专辑】Linux驱动
领取专属 10元无门槛券
私享最新 技术干货