首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Shell脚本编程进阶实战:从入门到高效自动化

第一时间看干货文章

【就业】简历模版

一、参数处理进阶:打造专业级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驱动

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O9cCEaUBECCWdawFRaKkg7ng0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券