Shell脚本基础Skill shell-scripting-fundamentals

此技能用于编写和修改Bash/shell脚本,涵盖脚本结构、变量、引用、条件语句和循环的现代最佳实践,帮助开发健壮、可维护的自动化脚本,适用于系统管理、DevOps和自动化任务。关键词:Shell脚本,Bash,脚本开发,自动化,系统管理,最佳实践,脚本结构,变量处理,条件循环。

DevOps 0 次安装 0 次浏览 更新于 3/25/2026

name: shell-scripting-fundamentals user-invocable: false description: 用于编写或修改Bash/shell脚本。涵盖脚本结构、变量、引用、条件语句和循环的现代最佳实践。 allowed-tools:

  • Read
  • Write
  • Edit
  • Bash
  • Grep
  • Glob

Shell脚本基础

编写健壮、可维护的shell脚本的核心模式和最佳实践。

脚本结构

始终以正确的shebang和安全选项开始脚本:

#!/usr/bin/env bash
set -euo pipefail

# 脚本描述在这里

安全选项解释

  • set -e: 在任何命令失败时退出
  • set -u: 对未定义变量报错
  • set -o pipefail: 如果管道中任何命令失败,则管道失败

变量

声明和赋值

# 在=周围没有空格
name="value"

# 使用readonly定义常量
readonly CONFIG_DIR="/etc/myapp"

# 在函数中使用local
my_function() {
    local result="computed"
    echo "$result"
}

始终引用变量

# 好 - 防止单词拆分和通配符扩展
echo "$variable"
cp "$source" "$destination"

# 坏 - 可能在空格或特殊字符处中断
echo $variable
cp $source $destination

默认值

# 如果未设置则使用默认值
name="${NAME:-default}"

# 如果未设置或为空则使用默认值
name="${NAME:-}"

# 如果未设置则分配默认值
: "${NAME:=default}"

# 如果未设置则报错
: "${REQUIRED_VAR:?错误: REQUIRED_VAR必须设置}"

条件语句

测试语法

# 现代语法 - 首选
if [[ -f "$file" ]]; then
    echo "文件存在"
fi

# 字符串比较
if [[ "$string" == "value" ]]; then
    echo "匹配"
fi

# 数字比较
if (( count > 10 )); then
    echo "大于10"
fi

# 正则表达式匹配
if [[ "$input" =~ ^[0-9]+$ ]]; then
    echo "数字输入"
fi

常见测试运算符

运算符 描述
-f 文件存在且是常规文件
-d 目录存在
-e 路径存在
-r 可读
-w 可写
-x 可执行
-z 字符串为空
-n 字符串不为空

循环

For循环

# 遍历列表
for item in one two three; do
    echo "$item"
done

# 遍历文件(使用通配符,而非ls)
for file in *.txt; do
    [[ -e "$file" ]] || continue  # 处理无匹配的情况
    process "$file"
done

# C风格for循环
for (( i = 0; i < 10; i++ )); do
    echo "$i"
done

While循环

# 从文件中读取行
while IFS= read -r line; do
    echo "$line"
done < "$filename"

# 使用进程替换读取
while IFS= read -r line; do
    echo "$line"
done < <(some_command)

数组

# 声明数组
declare -a files=()

# 添加元素
files+=("file1.txt")
files+=("file2.txt")

# 遍历所有元素
for file in "${files[@]}"; do
    echo "$file"
done

# 获取数组长度
echo "${#files[@]}"

# 通过索引访问
echo "${files[0]}"

命令替换

# 现代语法 - 首选
result=$(command)

# 嵌套替换
result=$(echo $(date))

# 避免旧式反引号
result=`command`  # 不要使用这个

函数

# 函数定义
process_file() {
    local file="$1"
    local output_dir="${2:-./output}"

    if [[ ! -f "$file" ]]; then
        echo "错误: 文件未找到: $file" >&2
        return 1
    fi

    # 处理文件
    cp "$file" "$output_dir/"
}

# 带参数调用
process_file "input.txt" "/tmp/output"

最佳实践总结

  1. 始终使用 #!/usr/bin/env bash 以获得可移植性
  2. 启用严格模式:set -euo pipefail
  3. 引用所有变量扩展
  4. 使用 [[ ]] 而非 [ ] 进行测试
  5. 使用 $(command) 而非反引号
  6. 在函数中声明局部变量
  7. 对项目列表使用数组
  8. 使用前检查命令存在:command -v cmd >/dev/null