Bash

Bourne Again Shell,Linux/macOS 默认 Shell,也是最通用的脚本语言之一。

变量

name="World"              # 赋值(等号两侧不能有空格)
echo "Hello, $name!"
echo "Hello, ${name}!"    # 推荐加花括号,避免歧义
 
readonly PI=3.14          # 只读变量
unset name                # 删除变量

字符串

str="Hello World"
echo ${#str}              # 长度:11
echo ${str:6}             # 截取:World
echo ${str:0:5}           # 截取:Hello
echo ${str/World/Bash}    # 替换:Hello Bash
echo ${str,,}             # 转小写
echo ${str^^}             # 转大写

数组

arr=(1 2 3 4 5)
echo ${arr[0]}            # 第一个元素
echo ${arr[@]}            # 所有元素
echo ${#arr[@]}           # 数组长度
arr+=(6)                  # 追加元素
 
# 关联数组(bash 4+)
declare -A map
map["key"]="value"
echo ${map["key"]}

条件判断

if [ "$x" -gt 10 ]; then
    echo "大于10"
elif [ "$x" -eq 10 ]; then
    echo "等于10"
else
    echo "小于10"
fi
 
# [[ ]] 更强大,支持正则、逻辑运算符
if [[ "$str" == *"Hello"* ]]; then echo "包含 Hello"; fi
if [[ "$str" =~ ^[0-9]+$ ]]; then echo "纯数字"; fi

常用判断条件

# 数值比较:-eq -ne -gt -ge -lt -le
# 字符串:== != -z(空) -n(非空)
# 文件:-f(文件存在) -d(目录存在) -r -w -x(权限)
[ -f "/etc/hosts" ] && echo "文件存在"
[ -d "/tmp" ] && echo "目录存在"

循环

for i in {1..5}; do echo $i; done
 
for ((i=0; i<5; i++)); do echo $i; done
 
# 遍历数组
for item in "${arr[@]}"; do echo "$item"; done
 
# while 循环
while [ $count -lt 5 ]; do
    echo $count
    ((count++))
done

函数

greet() {
    local name="$1"                  # 局部变量
    local greeting="${2:-Hello}"     # 带默认值的参数
    echo "$greeting, $name!"
}
 
greet "Alice"
greet "Bob" "Hi"
 
# 通过 echo 返回字符串结果
add() { echo $(( $1 + $2 )); }
result=$(add 3 4)

输入输出

read -p "请输入姓名: " name
read -s -p "请输入密码: " pass    # 静默输入
 
command > file.txt         # 覆盖
command >> file.txt        # 追加
command 2> error.txt       # 重定向错误
command > out.txt 2>&1     # 合并输出和错误
command < input.txt        # 从文件读取输入

特殊变量

$0        # 脚本名
$1 ~ $9   # 位置参数
$@        # 所有参数(数组形式)
$#        # 参数个数
$?        # 上一条命令退出码(0 为成功)
$$        # 当前进程 PID

错误处理

set -euo pipefail   # 推荐:遇错退出 + 未定义变量报错 + 管道失败检测
 
trap 'echo "错误发生在第 $LINENO 行"' ERR
trap 'cleanup' EXIT    # 退出时执行清理

参数扩展

${var:-default}    # 变量为空时使用默认值
${var:=default}    # 变量为空时赋值并返回默认值
${var:?message}    # 变量为空时打印错误并退出
 
# 路径处理
path="/home/user/file.txt"
echo ${path##*/}   # 文件名:file.txt
echo ${path%/*}    # 目录:/home/user
echo ${path##*.}   # 扩展名:txt

常用模式

# 检查命令是否存在
command -v git &>/dev/null || { echo "git 未安装"; exit 1; }
 
# 获取脚本所在目录
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 
# 并行执行并等待
for item in "${list[@]}"; do process "$item" & done
wait
 
# Here Document
cat <<EOF
第一行
第二行
EOF

调试

bash -x script.sh   # 追踪执行
bash -n script.sh   # 仅语法检查
set -x              # 脚本内开启追踪
set +x              # 关闭追踪