零基础通关:Shell 编程核心语法全景详解

零基础通关:Shell 编程核心语法全景详解

在 Linux 的核心世界里,掌握自动化脚本编写是每一个开发者与运维人员的必经之路。要写出高效、稳定的脚本,扎实的语法基本功是重中之重。

本篇博客专门为你梳理 Shell(基于主流的 Bash Shell)编程的完整语法体系 。我们抛开复杂的案例,完全面向零基础,用最通俗的语言、最规范的代码结构,带你逐一击破 Shell 的核心语法。


一、 认知奠基:Shell 脚本的"第一行"与运行结构

一个标准的 Shell 脚本是一个纯文本文件,通常以 .sh 为后缀 。在编写任何 Shell 脚本时,都有一个不可动摇的黄金启始结构。

1. 什么是 Shebang(#!/bin/bash)?

任何 Shell 脚本的第一行,必须是以下这串字符:

bash 复制代码
#!/bin/bash
  • 含义#! 组合在一起被称为 Shebang 。它紧跟的 /bin/bash 是系统路径,用来告诉操作系统:"当运行这个文本文件时,请立刻调用系统中的 Bash 解释器来翻译并执行后面的代码" 。

2. 编写与运行三步走

  1. 创建文件 :使用文本编辑器(如vim)创建一个文件 test.sh ,第一行写上#!/bin/bash

  2. 赋予权限 :Linux 中新创建的文件默认没有执行权限 。必须在终端执行 chmod +x test.sh 赋予其可执行权限 。

  3. 执行脚本 :在当前目录下通过 ./test.sh 即可一键运行。


二、 核心语法一:变量的定义、引用与作用域

变量是程序中用来存储动态数据的"盒子" 。Shell 中的变量使用非常灵活,但也伴随着极具迷惑性的"空格陷阱"。

1. 变量定义(等号两侧零空格)

bash 复制代码
# 正确示例:变量名=值
name="Geek"
age=18

# 错误示例!等号两边加了空格,系统会把它误认为是一个叫 my_name 的命令
my_name = "Geek" 

⚠️ 变量命名核心规范

  1. 变量名只能由字母、数字、下划线组成,且绝不能以数字开头 (如 1MyVar=123 是违法的) 。

  2. Bash 的关键字(如 if, for, while)不能用作变量名 。

2. 变量的引用($ 符号)

想使用盒子里存的数据,必须在变量名前面加上 $ 符号 。

bash 复制代码
echo $name     # 输出: Geek
echo ${name}   # 推荐写法!用花括号把变量名包裹起来,能精确防止字符拼接时发生歧义

3. 单引号 vs 双引号的区别(经典面试题)

当变量的值包含空格时,必须用引号包裹 。但单双引号的性质完全不同:

  • **''**单引号()------ 所见即所得:单引号内部的所有字符都会失去特殊含义,变成纯文本 。

  • **""**双引号()------ 允许解析 :双引号内部允许通过 $ 符号来读取其他变量的值 。

bash 复制代码
my_var="Linux"

echo '$my_var is powerful'   # 输出: $my_var is powerful
echo "${my_var} is powerful" # 输出: Linux is powerful

4. 命令替换(把命令结果存入变量)

如果你想把一个 Linux 命令在终端输出的结果拦截下来,存进变量里,需要使用 $(命令) 语法 :

bash 复制代码
# 获取当前日期并赋值给 shijian 变量
shijian=$(date "+%Y-%m-%d")
echo "今天的日期是: $shijian"

三、 核心语法二:条件判断与逻辑分支

让脚本能够根据不同的环境做出决策,是实现自动化监控和防御的基础 。

1. 条件判断的基本语法

bash 复制代码
if [ 条件判断式 ]; then
    # 条件为【真】时执行的代码
else
    # 条件为【假】时执行的代码
fi   # 以 fi (if的反写) 结束整个判断

⚠️ 空间陷阱 :中括号 [ 的内侧两边、以及 ] 的内侧两边,必须留有空格 !例如 if [$a -eq $b] 是错的,必须写成 if [ $a -eq $b ]

2. 常用判断条件分类

在 Shell 中,我们不能直接用 >, <, == 来比较数字,而是使用专属的英文字符缩写:

① 整数比较
  • -eq:等于 (Equal)

  • -ne:不等于 (Not Equal)

  • -gt:大于 (Greater Than)

  • -lt:小于 (Less Than)

  • -ge:大于等于 (Greater or Equal)

  • -le:小于等于 (Less or Equal)

② 字符串比较
  • ==:判定两个字符串是否一模一样

  • -z "字符串":判定字符串长度是否为 0(即是否为空)

③ 文件状态判定
  • -e 文件路径:判定文件或目录是否存在

  • -f 文件路径:判定这是否是一个"普通文件"

  • -d 文件路径:判定这是否是一个"目录(文件夹)"

3. 多分支语法示例(elif

bash 复制代码
score=85

if [ $score -ge 90 ]; then
    echo "优秀"
elif [ $score -ge 80 ]; then
    echo "良好"
else
    echo "及格/不及格"
fi

四、 核心语法三:循环控制结构

循环能够帮助我们批量处理重复性任务,或者让监控程序持续驻留运行 。

1. while循环(条件成立则一直循环)

只要中括号内的条件满足,就会源源不断地执行 dodone 之间的代码 。

bash 复制代码
# 经典的 7x24 小时全天候无限循环结构
while true   # 条件永远为真
do
    echo "每隔5秒轮询一次服务器状态..."
    sleep 5  # 核心技巧:必须加睡眠时间,防止死循环空转榨干服务器 CPU!
done # 循环体结束

2. for 循环(遍历固定范围)

当你需要依次处理一组已知的数据、文件或列表时,for 循环是最佳选择。

bash 复制代码
# 遍历普通列表
for ip in 192.168.1.1 192.168.1.2 192.168.1.3
do
    echo "正在检查服务器: ${ip} 的连通性..."
done

五、 核心语法四:输出重定向与用户交互

脚本在执行过程中,必然涉及数据的输入与输出。

1. 输出重定向:>>>

默认情况下,echo 命令会将内容直接打印到屏幕上 。通过重定向符号,我们可以将内容转存到文件中(这正是写日志的核心底层机制) :

  • >****(覆盖写入):会清空目标文件原本的所有内容,然后写入新数据 。

  • >>****(追加写入) :保留原文件内容,在文件的末尾另起一行追加新数据(推荐用于写日志) 。

bash 复制代码
echo "当前任务开始执行" > /var/log/my.log   # 清空旧日志,开始写入
echo "步骤一完成" >> /var/log/my.log       # 在末尾追加记录,不会破坏前面的内容

2. 错误输出隔离:2>/dev/null

在执行一些敏感命令(如检测端口、备份数据库)时,如果命令报错,错误信息会弄脏控制台。

  • Linux 中,1代表标准输出,2 代表错误输出 。

  • /dev/null 是 Linux 的虚拟"黑洞",丢进去的数据会瞬间消失。

bash 复制代码
# 如果 rsync 报错了,报错信息会被静默屏蔽,不会打印到屏幕上
rsync -az /data /backup 2>/dev/null

3. 用户输入捕获:read 命令

如果脚本需要与执行它的人类进行交互,可以使用 read 命令实时捕获对方键盘输入的内容,并赋予变量 。

bash 复制代码
# -p 参数可以在要求输入前,先打印一段中文提示信息
read -p "请输入您想要备份的数据库名称: " db_name

echo "系统收到!即将为您开始备份 [${db_name}] 数据库..."

4. 文本流多行写入:cat << EOF 语法

当你需要通过脚本动态向某个配置文件(如邮件配置、网络配置)中追加写入连续的多行文字时,可以用 << EOF 将文本块包围起来 :

bash 复制代码
# 将 EOF 之间的三行配置,一次性安全追加到配置文件中
cat >> /etc/test.conf << EOF
server_name=localhost
port=8080
status=active
EOF

💡 初学者稳健通关三大定律

看完上面的语法,请在心里牢记这三条"排错军规",能帮你避开 90% 的低级脚本报错:

1.定义变量不留空格key="value",等号两边千万别敲空格 。

  1. 条件判断必留空格if [ $a -eq $b ],中括号内侧和比较符两边,必须有空格 。

  2. 安全审计多用追加 :除非特殊清空需求,日常输出日志请认准 >> 符号,防止一不小心覆盖掉核心资产数据 。

基础语法已经全部交代完毕了。你现在是否已经准备好,在你的本地 Rocky Linux 或是虚拟机中创建一个 test.sh 来亲手敲一下这些变量和条件判断了?如果在练习基础语法时遇到任何诡异的报错,随时贴出来,我们一起现场 Debug!

相关推荐
杨运交1 小时前
[045][Crypto模块]设计一个可扩展的加解密框架:策略模式与工厂模式实战
linux·运维·策略模式
shx_wei1 小时前
从函数调用到进程替换:使用 execl、CMake 与 PowerShell 构建一个多可执行程序
linux·c语言·windows·c
Dlrb12111 小时前
信息查询Web服务器-->电子商城信息查询项目
linux·服务器·数据库·html·嵌入式·epoll·数据查询
纳兰青华2 小时前
在 PVE 上通过 LXC 部署 Ubuntu 24.04:为 OpenClaw 打造轻量高效的 AI 环境
linux·ai编程
Auv开心2 小时前
Ubuntu 20.04 默认视频播放器(Totem)无法播放 MP4 文件,通常是因为缺少多媒体编解码器。以下是几种解决方法:
linux·ubuntu·音视频
seacracker2 小时前
Ceph 太重运维成本高?轻量统一存储 PowerFS 对比测评(HPC/AI 场景首选)
运维·人工智能·ceph·ai存储·统一存储
ZhengO_Oz2 小时前
虚拟机CentOS 网络配置【实操】
运维·服务器·网络
天空'之城2 小时前
Linux 系统编程 15:UDP 编程
linux·系统编程·udp协议