bash 基础编程的核心语法

shell 和 bash 的区别

什么是 "shell"?

"shell"(中文常译为 "壳")是用户与操作系统内核(Kernel)之间的 "中间程序",它的核心作用是:

  • 接收用户输入的命令(比如ls查看文件、cd切换目录);
  • 将命令翻译成内核能理解的语言,让内核执行操作;
  • 再将内核的执行结果返回给用户。
    简单说,shell 就是 "用户操作内核的桥梁"。没有 shell,用户无法直接与内核交互(比如你在终端敲的所有命令,都需要 shell 来解析执行)。

"bash" 是什么?

"bash" 的全称是 "Bourne Again SHell"("再一次的 Bourne 壳"),它是众多 shell 实现中的一种,由 GNU 组织开发,诞生于 1989 年,目的是替代早期的 Bourne shell(sh,1979 年推出的第一个主流 shell)。

bash 的特点是:

  • 兼容性强:完全兼容 Bourne shell(sh)的语法,老的 sh 脚本可以直接在 bash 中运行;
  • 功能丰富:在 sh 的基础上增加了很多实用功能(比如数组、函数、更灵活的条件判断、命令补全等);
  • 应用广泛:目前几乎所有 Linux 发行版(如 Ubuntu、CentOS)、macOS(默认 shell,不过最新版本可能切换为 zsh,但仍支持 bash)都将 bash 作为默认 shell,是最主流的 shell 实现。

区别

概念 本质 包含关系 典型应用
shell 命令行解释器的统称(类别) 包含 bash、zsh、ksh 等 作为用户与内核的交互接口
bash shell 的一种具体实现(实例)全称 Bourne Again SHell,shell 的主流实现 是 shell 的子集,最常用的一种 作为默认 shell,执行 shell 脚本
shell 脚本 用 shell 语法编写的自动化脚本 可由 bash、zsh 等多种 shell 执行 批量处理、自动化任务等
bash 脚本 用 bash 语法编写的.sh文件 自动化执行命令(批量处理、定时任务等) 本质是 "命令的组合与逻辑控制"
  • 当我们说 "写 shell 脚本" 时,90% 以上的场景其实是 "写 bash 脚本"(因为 bash 最常用);而 "bash 编程" 就是用 bash 的语法规则来编写这类脚本,实现命令的自动化组合。
  • zsh(macOS 新默认 shell),它们的基础语法和 bash 很像(因为都兼容 sh),但增加了各自的扩展功能 ------ 但核心逻辑仍属于 "shell 编程" 的范畴。

bash 基础编程的核心语法

核心语法模块

1. 变量操作(基础中的基础)

核心语法

  • 赋值:变量名=值(等号两侧无空格,踩坑重灾区)
  • 使用:变量名 或 {变量名}(加{}避免歧义,如${name}123)
  • 只读变量:readonly 变量名(赋值后无法修改)
  • 删除变量:unset 变量名(删除后变量值为空)
  • 值为字符串:字符串可以用单引号,也可以用双引号,也可以不用引号

字符串特殊操作

需求 语法示例 结果(假设name="test")
取字符串长度 ${#name} 4
截取子串(从索引 0 开始) ${name:1:2}(从 1 取 2 个) es
单引号(原样输出) echo '${name}' ${name}(不解析变量)
双引号(解析变量) echo "${name}" test(解析变量值)
  • 示例

    bash 复制代码
    count=1          # 正确赋值(无空格)
    name="test"      # 双引号解析变量(若有空格需用双引号,如name="my test")
    echo ${count}    # 输出1
    echo ${#name}; # 4 字符串长度
    echo ${name:1:2}; # es 从第1个字符开始,取2个字符
    echo "------- ${name} -----------"; # ------- test -----------
    readonly count   # 设为只读,后续count=2会报错
    unset name       # 删除name,echo $name输出空
    DATE1=`date`;
    DATE2=`date +%Y-%m-%d`;
    echo $DATE1; # 2025年10月17日 星期五 16时52分01秒 CST
    echo $DATE2; # 2025-10-17

2. 数组操作(批量数据处理)

核心语法

  • 定义数组:数组名=(元素1 元素2 元素3)(元素用空格分隔)
  • 取单个元素:${数组名[索引]}(索引从 0 开始)
  • 取所有元素:{数组名\[\*\]} 或 {数组名[@]}(双引号下@更安全,元素含空格时不拆分)
  • 数组长度:${#数组名[@]}(同字符串长度语法)

示例

bash 复制代码
arr=(10 20 30 "hello bash")  # 含空格元素需用双引号
echo ${arr[0]}               # 输出10(第一个元素)
echo ${arr[*]}							 # 输出10 20 30 hello bash(所有元素)
echo ${arr[@]}               # 输出10 20 30 hello bash(所有元素)
echo ${#arr[@]}              # 输出4(数组长度)
# 遍历数组(推荐用@,兼容含空格元素)
for val in "${arr[@]}"; do
  echo "元素:$val"
done

3. 脚本参数传递(运行时传值)

核心变量(运行脚本时用:./test.sh 参数1 参数2)

变量 含义 示例(./test.sh 10 20)
$0 脚本自身路径 / 文件名 ./test.sh
1−1-1−n 第 1 到第 n 个参数 参数1 1=10,参数2 2=20
$# 参数总数 2
$* 所有参数(视为单个字符串) 10 20
$@ 所有参数(视为独立字符串) 10 20(遍历更安全)

示例

bash 复制代码
# 脚本内容(test.sh)
echo "脚本名:$0"
echo "参数总数:$#"
echo "第一个参数:$1"
echo "所有参数:$@"

# 运行脚本:./test.sh 5 8
# 输出:
# 脚本名:./test.sh
# 参数总数:2
# 第一个参数:5
# 所有参数:5 8

4. 运算符

  • 支持多种运算符,包括:

  • 算数运算符

    • 条件表达式要放在方括号之间,并且要有空格,例如:

      bash 复制代码
      # [ "\$a"=="\$b" ]是错误的,必须写成 [ "\$a" == "\$b" ]
      a=1; b=2
      if [ "$a"=="$b" ]; then d="true"; else d="false"; fi
      echo $d  # 输出 true(错误,虽然1≠2,但被当作非空字符串判断)
      # == 前后无空格 此时 bash 会将 "$a"=="$b" 整体视为一个单一字符串
      # 判断逻辑变成:"这个字符串是否非空"(因为 [ ] 中单独的字符串会被判断为 "非空即真")
  • 关系运算符

  • 布尔运算符

  • 逻辑运算符

  • 字符串运算符

  • 文件测试运算符

算术运算

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

  • expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
    • 乘号*需转义
  • 两种更优的现代写法:
    • 方式 1:$((...)) (推荐):无需转义,支持加减乘除取余,写法更简洁:

      bash 复制代码
      # 整数运算(推荐$((...)))
      total=$((3 + 2))  # 结果5,无需expr和转义
      total1=$((5 * 2)) # 结果10,乘号不用加\
      echo "3 + 2 = $total"  # 输出:3 + 2 = 5
      echo "5 * 2 = $total1"  # 输出:5 * 2 = 10
      # 浮点数运算(用bc)设置scale变量来控制小数点后的位数 
      # bc(Basic Calculator)是Linux中的一个命令行计算器工具,它支持任意精度的数值计算。
      a=5
      b=2
      echo "scale=2; $a / $b" | bc  # 输出2.50(保留2位小数)
    • 方式 2:\[...\]:与`((...))` 类似,兼容性稍弱但写法简单:

      bash 复制代码
      total2=$[5 / 2]  # 结果2(bash仅支持整数除法)
      echo "5 / 2 = $total2"  # 输出:5 / 2 = 2
算术运算符
运算符 说明
+ 加法
- 减法
* 乘法
/ 除法
% 取余
= 赋值
== 相等,比较两个数字,相同返回true;
!= 不相等,比较两个数字,不相同返回true;
bash 复制代码
total=`expr 3 + 2`
echo "参数总和为:$total" # 5
total2=`expr 5 - 2`
echo "参数差为:$total2" # 3
total3=`expr 5 \* 2`
echo "参数积为:$total3" # 10
total4=`expr 5 / 2`
echo "参数商为:$total4" # 2
total5=`expr 5 % 2`
echo "参数余为:$total5" # 1

a=1
b=2
c=1
# 判断 a 是否等于 b,将结果(true/false)赋值给 d
if [ "$a" == "$b" ]; then
  d="true"
else
  d="false"
fi

echo "a == b ? $d"  # 输出:a == b ? false

# 同理判断 a 和 c(相等)
if [ "$a" == "$c" ]; then
  e="true"
else
  e="false"
fi

echo "a == c ? $e"  # 输出:a == c ? true

# 判断 a 是否不等于 b,将结果(true/false)赋值给 d
if [ "$a" != "$b" ]; then
  d="true"
else
  d="false"
fi

# 同理判断 a 和 c(是否不相等)
if [ "$a" != "$c" ]; then
  e="true"
else
  e="false"
fi

echo "a == b ? $d"  # 输出:a == b ? true
echo "a == c ? $e"  # 输出:a == c ? false
关系运算符
  • 关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
    • 六个关系运算符
运算符 说明
-eq 相等
-ne 不相等
bash 复制代码
# -eq
if [ $a -eq $c ]
then
   echo " $a -eq $c: 检测两个数是否相等,相等返回 true"
else
   echo "$a -eq $c: 检测两个数是否相等,不相等返回 false"
fi
# -ne
if [ $a -ne $b ]
then
   echo "$a -ne $b: 检测两个数是否不相等,不相等返回 true"
else
   echo "$a -ne $b : 检测两个数是否不相等,相等返回 false"
fi
# -gt
if [ $b -gt $a ]
then
   echo "$b -gt $a: 检测左边的数是否大于右边的数,大于返回 true"
else
   echo "$b -gt $a: 检测左边的数是否大于右边的数,不大于返回 false"
fi
# -lt
if [ $a -lt $b ]
then
   echo "$a -lt $b: 检测左边的数是否小于右边的数,小于返回 true"
else
   echo "$a -lt $b: 检测左边的数是否小于右边的数,不小于返回 false"
fi
# -ge
if [ $b -ge $a ]
then
   echo "$b -ge $a: 检测左边的数是否大于等于右边的数,大于等于返回 true"
else
   echo "$b -ge $a: 检测左边的数是否大于等于右边的数,不大于等于返回 false"
fi
# -le
if [ $a -le $b ]
then
   echo "$a -le $b: 检测左边的数是否小于等于右边的数,小于等于返回 true"
else
   echo "$a -le $b: 检测左边的数是否小于等于右边的数,不小于等于返回 false"
fi
布尔运算符
运算符 说明
-a 与运算,两个表达式都为 true 才会返回 true
-o 或运算,有一个表达式为 true 就返回 true
! 非运算,取反,表达式为 true 会返回 false
bash 复制代码
a=1
b=2
# 与运算符 -a
# 判断 a 是否大于等于 b 且 a 是否小于等于 b,将结果(true/false)赋值给 d
if [ $a -ge $b -a $a -le $b ]; then
  d="true"
else
  d="false"
fi

echo "a 是否大于等于 b 且 a 是否小于等于 b ? $d"  # 输出:a 是否大于等于 b 且 a 是否小于等于 b ? false

# 或运算符 -o
# 判断 a 是否大于等于 b 或 a 是否小于等于 b,将结果(true/false)赋值给 d
if [ $a -ge $b -o $a -le $b ]; then
  d="true"
else
  d="false"
fi

echo "a 是否大于等于 b 或 a 是否小于等于 b ? $d"  # 输出:a 是否大于等于 b 或 a 是否小于等于 b ? true

# 非运算符!
if [ ! $a -eq $b ]
then
   echo "! $a -eq $b: 检测两个数是否不相等,不相等返回 true"
else
   echo "! $a -eq $b: 检测两个数是否不相等,相等返回 false"
fi
逻辑运算符
运算符 作用(逻辑关系)
&& 逻辑与(两者都为真)
|| 逻辑或(其中之一为真)
bash 复制代码
a=2;
b=6;
# 1. 现代写法([[ ]] + &&/||,推荐)
if [[ $a -gt 1 && $b -lt 8 ]]; then
  echo "&&条件成立"  # 会执行(2>1 且 6<8)
fi
if [[ $a -gt 1 || $b -lt 8 ]]; then
  echo "||条件成立"  # 会执行(2>1 且 6<8)
fi


# 2. 传统写法([ ] + -a/-o,需注意空格)
if [ $a -gt 1 -a $b -lt 8 ]; then  # -a 表示"且"
  echo "-a条件成立"  # 会执行
fi
if [ $a -gt 1 -o $b -lt 8 ]; then  # -a 表示"且"
  echo "-0条件成立" # 会执行
fi

5. 条件判断(if/else 逻辑)

6. 循环(重复执行逻辑)

7. 脚本执行基础

相关推荐
和编程干到底6 小时前
C++基础
开发语言·c++
Z_Xshan6 小时前
docker 容器web站点 中文文件名访问404问题
linux·开发语言·docker
kkkkk0211067 小时前
【Rust创作】Rust 错误处理:从 panic 到优雅控制
开发语言·算法·rust
John.Lewis7 小时前
C++初阶(14)list
开发语言·c++·笔记
hsjkdhs8 小时前
C++文件操作
开发语言·c++
hoiii1878 小时前
C#实现近7天天气预报
开发语言·c#
赵谨言8 小时前
基于Python楼王争霸劳动竞赛数据处理分析
大数据·开发语言·经验分享·python
亦陈不染8 小时前
c#入门详解(刘铁锰)06 - 数据持久化:TXT文本保存、序列化与反序列化(附详细源码)
开发语言·计算机视觉·c#·wpf
ceclar1238 小时前
C++Lambda表达式
开发语言·c++·算法