Shell 脚本基础 #

脚本基础 #

脚本结构 #

bash
#!/bin/bash

# 这是注释
echo "Hello, World!"

# 脚本说明
# 第一行是 shebang,指定解释器
# 常见解释器:
# #!/bin/bash
# #!/bin/sh
# #!/usr/bin/env bash

执行脚本 #

bash
# 添加执行权限
$ chmod +x script.sh

# 直接执行
$ ./script.sh

# 使用解释器执行
$ bash script.sh
$ sh script.sh

# 在当前 shell 执行
$ source script.sh
$ . script.sh

# 调试模式
$ bash -x script.sh
$ bash -n script.sh    # 只检查语法

变量 #

变量定义 #

bash
#!/bin/bash

# 定义变量(等号两边不能有空格)
name="John"
age=25

# 使用变量
echo $name
echo ${name}
echo "My name is $name"

# 只读变量
readonly PI=3.14159

# 删除变量
unset name

# 变量默认值
echo ${name:-"default"}      # 如果 name 未定义,使用 default
echo ${name:="default"}      # 如果 name 未定义,赋值并使用
echo ${name:?"error"}        # 如果 name 未定义,显示错误
echo ${name:+"value"}        # 如果 name 已定义,使用 value

特殊变量 #

text
┌─────────────────────────────────────────────────────────────┐
│                    特殊变量                                 │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   $0        脚本名称                                        │
│   $1-$n     位置参数                                        │
│   $#        参数个数                                        │
│   $@        所有参数(每个参数独立)                         │
│   $*        所有参数(作为一个整体)                         │
│   $?        上一个命令的退出状态                             │
│   $$        当前进程 PID                                    │
│   $!        后台进程 PID                                    │
│   $_        上一个命令的最后一个参数                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

环境变量 #

bash
# 查看环境变量
$ env
$ printenv

# 常见环境变量
$ echo $HOME
$ echo $PATH
$ echo $USER
$ echo $PWD
$ echo $SHELL

# 设置环境变量
export MY_VAR="value"

# 在脚本中使用
#!/bin/bash
export PATH=$PATH:/new/path

数据类型 #

字符串 #

bash
#!/bin/bash

# 定义字符串
str1='Hello'
str2="World"
str3="Hello $str2"    # 双引号支持变量展开
str4='Hello $str2'    # 单引号不展开

# 字符串长度
echo ${#str1}

# 子字符串
echo ${str1:0:3}      # 从位置 0 开始,取 3 个字符

# 字符串拼接
full="${str1} ${str2}"

# 字符串替换
echo ${str1/ll/LL}    # 替换第一个
echo ${str1//l/L}     # 替换所有

# 删除匹配
echo ${str1#He}       # 删除开头匹配
echo ${str1%lo}       # 删除结尾匹配

数组 #

bash
#!/bin/bash

# 定义数组
arr=(1 2 3 4 5)
arr2=("a" "b" "c")

# 访问元素
echo ${arr[0]}        # 第一个元素
echo ${arr[-1]}       # 最后一个元素

# 所有元素
echo ${arr[@]}
echo ${arr[*]}

# 数组长度
echo ${#arr[@]}
echo ${#arr[*]}

# 添加元素
arr+=(6 7 8)

# 遍历数组
for i in "${arr[@]}"; do
    echo $i
done

# 切片
echo ${arr[@]:1:3}    # 从索引 1 开始,取 3 个

# 关联数组
declare -A person
person[name]="John"
person[age]=25
echo ${person[name]}

条件判断 #

if 语句 #

bash
#!/bin/bash

# 基本 if
if [ condition ]; then
    echo "true"
fi

# if-else
if [ condition ]; then
    echo "true"
else
    echo "false"
fi

# if-elif-else
if [ condition1 ]; then
    echo "1"
elif [ condition2 ]; then
    echo "2"
else
    echo "other"
fi

条件测试 #

bash
#!/bin/bash

# 数值比较
# -eq  等于
# -ne  不等于
# -gt  大于
# -lt  小于
# -ge  大于等于
# -le  小于等于

if [ $a -eq $b ]; then
    echo "equal"
fi

# 字符串比较
# =    等于
# !=   不等于
# -z   空字符串
# -n   非空字符串

if [ "$str1" = "$str2" ]; then
    echo "equal"
fi

# 文件测试
# -e    存在
# -f    普通文件
# -d    目录
# -r    可读
# -w    可写
# -x    可执行
# -s    非空

if [ -f "$file" ]; then
    echo "file exists"
fi

# 逻辑运算
# -a    与
# -o    或
# !     非

if [ $a -gt 0 -a $a -lt 10 ]; then
    echo "0 < a < 10"
fi

# 使用 && 和 ||
if [[ $a -gt 0 && $a -lt 10 ]]; then
    echo "0 < a < 10"
fi

case 语句 #

bash
#!/bin/bash

read -p "Enter a number: " num

case $num in
    1)
        echo "One"
        ;;
    2)
        echo "Two"
        ;;
    [3-5])
        echo "Three to Five"
        ;;
    *)
        echo "Other"
        ;;
esac

循环 #

for 循环 #

bash
#!/bin/bash

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

# 遍历范围
for i in {1..5}; do
    echo $i
done

# 步长
for i in {1..10..2}; do
    echo $i
done

# C 风格
for ((i=0; i<5; i++)); do
    echo $i
done

# 遍历文件
for file in *.txt; do
    echo $file
done

# 遍历数组
arr=(a b c d)
for item in "${arr[@]}"; do
    echo $item
done

while 循环 #

bash
#!/bin/bash

# 基本 while
i=0
while [ $i -lt 5 ]; do
    echo $i
    ((i++))
done

# 读取文件
while read line; do
    echo $line
done < file.txt

# 无限循环
while true; do
    echo "Press Ctrl+C to exit"
    sleep 1
done

# 按条件退出
while :; do
    read -p "Enter 'q' to quit: " input
    if [ "$input" = "q" ]; then
        break
    fi
done

until 循环 #

bash
#!/bin/bash

# until 循环(条件为假时执行)
i=0
until [ $i -ge 5 ]; do
    echo $i
    ((i++))
done

循环控制 #

bash
#!/bin/bash

# break 退出循环
for i in {1..10}; do
    if [ $i -eq 5 ]; then
        break
    fi
    echo $i
done

# continue 跳过当前迭代
for i in {1..5}; do
    if [ $i -eq 3 ]; then
        continue
    fi
    echo $i
done

函数 #

定义函数 #

bash
#!/bin/bash

# 定义函数
function greet() {
    echo "Hello, $1!"
}

# 简写
greet() {
    echo "Hello, $1!"
}

# 调用函数
greet "John"

# 带返回值
add() {
    echo $(($1 + $2))
}
result=$(add 3 5)
echo $result

# 返回状态码
check_file() {
    if [ -f "$1" ]; then
        return 0
    else
        return 1
    fi
}
check_file "test.txt"
if [ $? -eq 0 ]; then
    echo "File exists"
fi

局部变量 #

bash
#!/bin/bash

my_function() {
    local local_var="local"
    global_var="global"
    echo "Inside: $local_var"
}

my_function
echo "Outside: $global_var"
echo "Outside: $local_var"    # 空值

输入输出 #

读取输入 #

bash
#!/bin/bash

# 读取用户输入
read -p "Enter your name: " name
echo "Hello, $name"

# 读取密码(不显示)
read -s -p "Enter password: " password
echo

# 读取多个值
read -p "Enter first and last name: " first last

# 限制输入时间
read -t 5 -p "Enter (5 seconds): " input

# 限制输入长度
read -n 1 -p "Press any key: " key

输出 #

bash
#!/bin/bash

# echo
echo "Hello"
echo -n "No newline"
echo -e "Tab:\tNewline:\n"

# printf
printf "Name: %s, Age: %d\n" "John" 25
printf "%-10s %5d\n" "John" 25
printf "%.2f\n" 3.14159

小结 #

通过本节学习,你应该掌握:

  1. 脚本基础:脚本结构、执行方式
  2. 变量:定义、使用、特殊变量
  3. 数据类型:字符串、数组
  4. 条件判断:if、case、测试条件
  5. 循环:for、while、until
  6. 函数:定义、参数、返回值
  7. 输入输出:read、echo、printf

下一步,我们将学习管道与重定向。

最后更新:2026-04-11