Bash

Linux Bash Shell 脚本编程入门速查表与常用语法备忘单。

#入门指南

#hello.sh 示例 (Hello World)

#!/bin/bash

VAR="world"
echo "Hello $VAR!" # => Hello world!

运行 Bash 脚本

$ bash hello.sh

#变量声明 (Variables)

NAME="John"

echo ${NAME}    # => John (变量引用)
echo $NAME      # => John (变量引用)
echo "$NAME"    # => John (变量引用)
echo '$NAME'    # => $NAME (原样单引号字面量)
echo "${NAME}!" # => John! (拼接变量)

NAME = "John"   # => 错误 (等号两边不能有空格)

#代码注释 (Comments)

# 这是单行 Bash 注释
: '
这是 Bash 中的
多行注释语法
'

多行注释使用 : ' 开始,以 ' 结尾。

#脚本参数 (Arguments)

表达式 说明
$1$9 第 1 到 第 9 个位置参数
$0 当前脚本本身的名称
$1 第一个传入参数
${10} 第 10 个位置参数(需加大括号)
$# 传入参数的总个数
$$ 当前 Shell 的进程 PID
$* 所有传入参数(作为一个整体字符串)
$@ 所有传入参数(保留各自参数边界)
$- 当前 Shell 开启的选项标志
$_ 上一条命令的最后一个参数

参阅: Shell 特殊参数说明

#函数定义 (Functions)

get_name() {
    echo "John"
}

echo "You are $(get_name)"

参阅: 函数详解

#条件判断 (Conditionals)

if [[ -z "$string" ]]; then
    echo "字符串为空"
elif [[ -n "$string" ]]; then
    echo "字符串非空"
else
    echo "其他情况"
fi

参阅: 条件判断详解

#括号语法总结 (Brace expansion)

echo {A,B}.js     # => A.js B.js
echo {A,B}        # => A B
echo {1..5}       # => 1 2 3 4 5
echo {1..10..2}   # => 1 3 5 7 9
echo {a..e}       # => a b c d e

#命令替换与执行 (Shell execution)

echo "当前目录是 $(pwd)"
echo "当前目录是 `pwd`" # 旧式语法

#变量展开 (Parameter Expansions)

#基础语法 (Syntax)

语法 说明
${FOO:-val} 如果 FOO 未设置或为空,返回 val
${FOO:=val} 如果 FOO 未设置或为空,将其赋值为 val 并返回
${FOO:+val} 如果 FOO 已设置且非空,返回 val
${FOO:?err} 如果 FOO 未设置或为空,打印 err 报错并退出

#字符串截取与切片 (Slicing)

FOO="Hello World"
echo ${FOO:0:5}   # => Hello (从下标0开始截取5个字符)
echo ${FOO:6}     # => World (从下标6开始截取到末尾)
echo ${FOO: -5}   # => World (从末尾倒数第5个字符开始)

#路径处理 (Basepath & Dirpath)

SRC="/path/to/file.txt"
echo ${SRC##*/}   # => file.txt (获取文件名)
echo ${SRC%/*}    # => /path/to (获取目录路径)

#文本替换与转换 (Transform)

FOO="hello world"
echo ${FOO^}      # => Hello world (首字母大写)
echo ${FOO^^}     # => HELLO WORLD (全部转大写)
echo ${FOO/l/X}   # => Hexlo world (替换第一个 l)
echo ${FOO//l/X}  # => Hexxo worxd (替换所有 l)

#数组操作 (Bash Arrays)

#声明与定义 (Defining)

# 声明数组
Fruits=('Apple' 'Banana' 'Orange')

# 读取元素
echo ${Fruits[0]}           # => Apple
echo ${Fruits[@]}           # => Apple Banana Orange (所有元素)
echo ${#Fruits[@]}          # => 3 (数组长度)
echo ${#Fruits[0]}          # => 5 (第一个元素的长度)

#数组遍历 (Iteration)

for item in "${Fruits[@]}"; do
    echo "水果: $item"
done

#条件表达式详解 (Bash Conditionals)

#整数条件比较 (Integer)

比较运算符 含义 示例
-eq 等于 (Equal) [[ $a -eq $b ]]
-ne 不等于 (Not Equal) [[ $a -ne $b ]]
-lt 小于 (Less Than) [[ $a -lt $b ]]
-le 小于等于 [[ $a -le $b ]]
-gt 大于 (Greater Than) [[ $a -gt $b ]]
-ge 大于等于 [[ $a -ge $b ]]

#字符串比较 (String)

比较运算符 含义
= / == 字符串相同
!= 字符串不相同
-z 字符串为空 (Zero length)
-n 字符串非空 (Non-zero)

#文件状态判断 (File)

测试条件 说明
-e file 文件或目录是否存在
-f file 是否为普通文件
-d file 是否为目录
-r file 文件是否可读
-w file 文件是否可写
-x file 文件是否可执行
-s file 文件大小是否大于 0

#循环语句 (Bash Loops)

#For 循环 (For Loop)

# 列表遍历
for i in 1 2 3 4 5; do
    echo "数字: $i"
done

# C 语言风格循环
for ((i = 0; i < 5; i++)); do
    echo "索引: $i"
done

#While 循环 (While Loop)

count=1
while [ $count -le 5 ]; do
    echo "计数: $count"
    ((count++))
done

#读取文件逐行 (Reading lines)

while read -r line; do
    echo "读取行: $line"
done < input.txt

#其他实用技巧 (Miscellaneous)

#数值计算 (Numeric calculations)

$ echo $((1 + 2))        # => 3
$ echo $((5 * (2 + 3)))  # => 25

#重定向 (Redirection)

$ command > file.txt     # 重定向覆盖输出到文件
$ command >> file.txt    # 重定向追加输出到文件
$ command 2> error.log   # 仅重定向错误输出 (stderr)
$ command > file 2>&1    # 将标准输出和错误输出合并重定向