开篇:从"重复造轮子"到"模块化大师"
想象你在玩乐高:
Shell函数就是你的代码乐高积木,今天教你打造可复用的"超能力模块"!
# 方式1:正统派(推荐)
function greet() {
local name="$1"
echo "Hello, $name! 今天是$(date +%F)"
}
# 方式2:极简派
log_error() {
echo "[ERROR $(date +%T)] $@" >&2
}
行业惯例:
greet "Shell学徒" # 输出:Hello, Shell学徒! 今天是2023-08-01
log_error "磁盘空间不足" # 输出到标准错误流
is_root() {
[ $(id -u) -eq 0 ]
return $? # 可省略
}
is_root && echo "管理员模式" || echo "请使用sudo"
get_ip() {
local iface=$1
ip addr show $iface | grep -oP 'inet \K[\d.]+'
}
server_ip=$(get_ip eth0)
get_users() {
local users=($(cut -d: -f1 /etc/passwd))
echo "${users[@]}"
}
user_array=($(get_users)) # 注意外层括号
#!/bin/bash
# 日志工具
log::info() {
echo -e "\033[32m[INFO]\033[0m $(date '+%F %T') $@"
}
# 数学工具
math::add() {
echo $(($1 + $2))
}
# 安全工具
security::check_port() {
netstat -tuln | grep -q ":$1 "
}
source ./lib.sh
log::info "系统初始化开始"
security::check_port 80 && log::info "80端口已被占用"
result=$(math::add 10 20)
call_api() {
local method=$1
local url=$2
shift 2 # 移除非body参数
curl -X $method "$url" -d "$@"
}
call_api POST http://api.com name=John age=30
# 递归计算阶乘
factorial() {
local n=$1
[ $n -le 1 ] && echo 1 && return
echo $(( n * $(factorial $((n-1))) ))
}
factorial 5 # 输出120
before_install() {
echo "安装前检查..."
[ -f "/tmp/lock" ] && return 1
}
after_install() {
echo "清理临时文件..."
rm -f /tmp/*
}
main() {
before_install || exit 1
# 安装逻辑...
after_install
}
bad_func() {
count=10 # 全局变量!
}
slow_func() {
result=$(echo "scale=2; $1/$2" | bc) # 每次调用都启动bc
}
danger() {
rm -rf "/tmp/$1" # 如果$1为空...
}
#!/bin/bash
source ./lib.sh
deploy() {
local env=$1
local version=$2
log::info "开始部署[$env]环境v$version"
security::check_port 8080 && {
log::error "8080端口被占用"
return 1
}
# 模拟部署过程
for i in {1..5}; do
sleep 0.5
echo -n "." >&2
done
log::info "部署成功完成"
}
main() {
case "$1" in
prod) deploy prod "$2" ;;
test) deploy test "$2" ;;
*) echo "用法: $0 {prod|test} 版本号" ;;
esac
}
main "$@"
需求:
示例输出:
$ ./tester.sh login_test.yaml
[PASS] 测试登录功能-正常流 (0.2s)
[FAIL] 测试登录功能-错误密码 (预期401实际200)