LOADING

SHELL语法速查

linux

脚本声明与执行

  1. Shebang#!/bin/bash
  2. 执行方式
    • 赋权执行:chmod +x script.sh -> ./script.sh(开启子进程执行)
    • 解释器执行:bash script.sh(开启子进程执行)
    • 当前环境执行:source script.sh. script.sh(常用于加载配置/环境变量,不开启子进程)

变量参数

变量 说明 示例
$0 当前脚本的文件名(或 Shell 名称) $0./test.sh
$1$9 第 1 到第 9 个位置参数 $1a$2b$3c
${10} 第 10 个及以上的位置参数(必须使用大括号) ${10} → 第 10 个参数(若存在)
$# 位置参数的总个数(不含 $0 $#3
$@ 所有位置参数,每个参数作为独立的字符串 for arg in "$@" → 依次得到 abc
$* 所有位置参数,作为一个整体字符串(首个参数与末个参数之间由 IFS 分隔) "$*" 默认 → "a b c"(IFS 首字符为空格)
$? 上一条命令的退出状态码 ls /tmp; echo $? → 若成功则 0
$$ 当前 Shell 脚本的进程 ID(PID) echo $$ → 例如 12345
$! 最近一次放入后台执行的进程 PID sleep 10 & echo $! → 输出后台 sleep 命令的 PID

引号与转义

这是 Bash 解析机制的核心,决定了字符的“字面量”与“替换”行为。

  1. 反斜杠 \:转义
  2. 单引号 ''硬引号,原样输出
  3. 双引号 ""软引号,允许替换

命令替换与算术运算

  1. 命令替换:将命令的输出结果赋值给变量。
    • 推荐写法:VAL=$(command arg)
    • 旧写法:VAL=`command arg`
  2. 算术运算:Bash 原生只支持整数运算。
    • 推荐写法:$(( expression )),例如 RESULT=$(( 5 + 3 ))
    • 内部变量无需加 $$(( a + b )) 等同于 $(( $a + $b ))
    • 支持运算:+, -, *, /, %, **
    • 支持自增/自减:(( i++ )), (( i-- )), (( i += 2 ))

字符串操作

分类 语法 说明
获取长度 ${#VAR} 返回变量 VAR 的字符串长度
提取子串 ${VAR:offset:length} offset 位置(从0开始)取 length 个字符
默认值(不改变变量) ${VAR:-default} VAR 未设置或为空,返回 default,但不修改 VAR
默认值(改变变量) ${VAR:=default} VAR 未设置或为空,将其赋值为 default 并返回
替换(首个) ${VAR/pattern/replacement} 替换第一个匹配的 pattern
替换(全部) ${VAR//pattern/replacement} 替换所有匹配的 pattern
删除(头部,最短匹配) ${VAR#pattern} 从字符串开头删除最短匹配的 pattern
删除(头部,最长匹配) ${VAR##pattern} 从字符串开头删除最长匹配的 pattern
删除(尾部,最短匹配) ${VAR%pattern} 从字符串末尾删除最短匹配的 pattern
删除(尾部,最长匹配) ${VAR%%pattern} 从字符串末尾删除最长匹配的 pattern

条件判断

测试原语

  • [ condition ]:POSIX 标准测试,注意括号两侧必须有空格。
  • [[ condition ]]Bash 增强测试,推荐使用。支持正则匹配 =~,支持逻辑运算符 &&||,且对空格和引号的容错率更高。

文件判断

参数 说明
-f 存在且为普通文件
-d 存在且为目录
-e 存在(文件或目录)
-r 存在且可读
-x 存在且可执行

字符串判断

参数 说明
-z 字符串长度为 0
-n 字符串长度不为 0
=== 字符串相等
!= 字符串不等

数值判断

参数 说明
-eq 等于 (equal)
-ne 不等于 (not equal)
-gt 大于 (greater than)
-lt 小于 (less than)
-ge 大于或等于 (greater or equal)
-le 小于或等于 (less or equal)

分支语句

  1. if 分支
    if [[ condition ]]; then
        commands
    elif [[ condition ]]; then
        commands
    else
        commands
    fi
  2. case 分支(常用于菜单/参数解析,支持通配符):
    case "$VAR" in
        pattern1)
            commands
            ;;
        pattern2|pattern3)
            commands
            ;;
        *)
            commands  # 默认分支
            ;;
    esac

循环

  1. for 循环
    • 遍历列表:for item in list; do commands; done
    • C语言风格(常用于计数):for (( i=0; i<10; i++ )); do commands; done
  2. while 循环 条件为真时执行:
    while [[ condition ]]; do
        commands
    done
  3. until 循环 条件为假时执行:
    until [[ condition ]]; do
        commands
    done
  4. 循环控制
  • break
  • continue

数组

Bash 只支持一维数组,索引从 0 开始。

  1. 定义
    • 索引数组:ARR=(val1 val2 val3)
    • 关联数组(字典,需提前声明):declare -A MAP; MAP=([key1]=val1 [key2]=val2)
  2. 取值
    • 单个元素:${ARR[index]}
    • 所有元素:${ARR[@]}(常用) 或 ${ARR[*]}
  3. 获取信息
    • 数组长度:${#ARR[@]}
    • 所有索引(键):${!ARR[@]}

函数

  1. 定义
    function func_name() {
        commands
    }
    # 或
    func_name() {
        commands
    }
  2. 参数与返回值
    • 函数内部通过 $1, $2, $@ 接收参数,与脚本接收参数机制完全一致。
    • 函数没有返回字符串的机制return 只能返回 0-255 的整数(表示执行状态)。
    • 返回字符串的标准做法:函数内部 echo 输出,外部用命令替换捕获 result=$(func_name)
  3. 变量作用域
    • 默认函数内的变量是全局的(会污染外部)。
    • 必须使用 local VAR=value 声明函数内的局部变量。

逻辑组合与子进程

  1. 逻辑组合
    • cmd1 && cmd2:cmd1 成功(退出码为0)才执行 cmd2。
    • cmd1 || cmd2:cmd1 失败(退出码非0)才执行 cmd2。
  2. 子进程执行
    • ( commands ):括号内的命令在一个全新的子 Shell 中执行,内部的变量修改、目录切换(cd)完全不影响当前父 Shell。
  3. 进程替换(进阶,但很有用):
    • <(cmd):将 cmd 的输出视为一个临时文件描述符,传给另一个命令。