文章总结: 文档系统介绍Bash脚本语言基础,涵盖脚本创建执行、变量分类、字符串与数组处理、条件判断、循环语句及函数定义等核心语法。文中详细对比了赋权与临时运行的区别,解析了特殊变量用法,并针对变量引用规范和循环逻辑差异提供了实操建议,旨在帮助读者掌握自动化系统管理任务的必备技能。 综合评分: 75 文章分类: 安全开发,安全培训,实战经验
什么是Bash
guowei guowei
网络安全直通车
2026年3月13日 10:28 北京
Bash是兼容 sh 的主流 Shell 脚本语言,默认搭载于多数 Linux 发行版及 MacOS 终端,核心用于自动化系统管理任务(如备份);其脚本由一系列 Bash 命令组成,无需编译可直接运行,支持变量(局部 / 全局 / 环境变量)、字符串操作、数组、条件判断(if/case)、循环(for/while/until)、函数等核心语法,执行时需通过 chmod 命令赋予文件权限或用 . ./脚本名.sh 临时运行,是高效完成复杂终端任务的关键工具。
一、Bash 基础认知
-
定义与定位
:Bash 是 GNU 组织开发的 Shell 脚本语言,兼容 UNIX 标准 Shell(sh),是多数 Linux 发行版的默认 Shell,核心作用是连接用户与操作系统内核,接收并处理用户命令后传递给内核,无需编译即可直接运行脚本。
-
应用场景
:专注于 自动化系统管理任务(如备份),可组合多条命令实现复杂终端操作,替代单一单行命令提升效率。
-
运行环境与权限标识
:
- 运行环境:Linux 发行版(如 Ubuntu)、MacOS 终端。
- 权限标识:终端中
$代表普通用户,#代表超级用户(root)。
二、脚本创建与执行
表格
| 操作步骤 | 具体命令 / 说明 | 关键注意事项 |
| — | — | — |
| 创建脚本 | vi test.sh(用 vi 编辑器创建 .sh 后缀文件) | 脚本首行必须为 #!/bin/bash,指定解释器路径 |
| 脚本结构 | 1. 解释器声明(#!/bin/bash);2. 注释(# 开头);3. 功能命令(如 echo 输出) | 注释仅用于说明,不会执行;#! 是特殊标记,非普通注释 |
| 执行方式 | 1. 赋权运行:chmod 777 test.sh + ./test.sh2. 临时运行:. ./test.sh | 直接执行 ./test.sh 会提示权限不足,需先赋权;临时运行无需改变文件权限 |
三、核心语法详解
(一)变量
-
基本规则
:
- 类型:默认均为字符串,可通过 declare 显式定义类型。
- 命名:由字母、下划线、数字组成,开头必须是字母或下划线,等号两边无空格(如
str=1正确,str = 1错误)。
-
变量分类
:
- 局部变量:函数内定义,默认全局有效,添加
local关键字后仅限函数内使用。 - 全局变量:当前 Shell 会话(终端)内有效,切换终端失效。
- 环境变量:全局变量前加
export(如export a=1),可由父 Shell 传递给子 Shell,会话销毁后失效,需写入启动文件永久保存。
-
变量操作
:
- 引用:推荐用
${变量名}形式(如${str}),避免长字符中识别错误(如${str}1正确,$str1可能误判)。 - 赋值 / 修改:直接重新赋值(如
a=1→a=2),只读变量(readonly c=1)不可修改。 - 删除:
unset 变量名(如unset a),删除后变量无值。
(二)特殊变量
表格
| 变量 | 描述 | 示例 | | — | — | — | | $0 | 当前脚本的文件名或解释器 | 执行 ./test.sh 时,$0 为 test.sh | | $n(n≥1) | 传递给脚本 / 函数的第 n 个参数 | 执行 ./test.sh 11 22 时,$1=11、$2=22,≥10 需用 ${10} | | $# | 传递的参数个数 | 执行 ./test.sh 11 22 时,$#=2 | | $* | 所有参数(整体视为一个数据) | 执行 ./test.sh 11 22 时,$*=11 22 | | $@ | 所有参数(每个参数单独为一份数据) | 执行 ./test.sh 11 22 时,$@=11 22(双引号包裹时与 $* 有差异) | | $? | 上个命令 / 函数的退出状态 / 返回值 | 函数返回 3 时,echo $? 输出 3 | | $$ | 当前 Shell 进程 ID | 执行脚本时,$$ 为脚本所在进程 ID |
(三)字符串操作
-
长度获取
:
${#str}(如str="123456",${#str}输出 6)。 -
拼接
:直接拼接无空格,支持引号包裹(如
temp1=${n1}${n2}、temp2="${n1}${n2}",n1=ab、n2=cd 时均输出 abcd)。 -
截取
:
-
${string#*chars}:从左边第一个 chars 后截取(
${str#*/}输出 /:baidu.com/.c)。 -
${string##*chars}:从左边最后一个 chars 后截取(
${str##*/}输出 .c)。 -
${string%*chars}:从右边第一个 chars 前截取(
${str%/*}输出 http//:baidu.com)。 -
${string%%*chars}:从右边最后一个 chars 前截取(
${str%%/*}输出 http)。 -
从左边截取:
${string:start:length}(如str="http//:baidu.com/.c",${str:7:5}输出 baidu),无 length 则截取到末尾(${str:7}输出 baidu.com/.c)。 -
从右边截取:
${string:0-start:length}(如${str:0-7:5}输出 .com/),无 length 则截取到末尾(${str:0-7}输出 .com/.c)。 -
按字符截取:
(四)数组
-
基本规则
:仅支持一维数组,定义形式
array=(n1 n2 n3)(等号两边无空格,元素用空格分隔),元素可混合数字与字符串(如array=(1 2 ab))。 -
核心操作
:
- 访问元素:
${array[index]}(如${array[0]}访问第一个元素)。 - 新增元素:
array[3]=cd(直接指定索引赋值,无需连续索引)。 - 所有元素:
${array[*]}或${array[@]}。 - 长度获取:
${#array[*]}(元素个数)、${#array[4]}(索引 4 元素的字符串长度)。 - 拼接:
array3=(${array1[@]} ${array2[@]})(合并 array1 和 array2)。 - 删除:
unset array[2](删除索引 2 元素)、unset array2(删除整个数组)。
(五)条件判断
-
if 语句
:
- 单分支:支持 3 种形式,
if []; then(then 与 if 同行需加;)、if [](then 换行)、if (())(数值判断更简洁)。 - 双分支:
if 条件; then 语句1; else 语句2; fi。 - 多分支:
if 条件1; then 语句1; elif 条件2; then 语句2; else 语句3; fi。 - 比较运算符:-eq(等于)、-ne(不等于)、-gt(大于)、-ge(大于等于)、-lt(小于)、-le(小于等于)(如
if [ "$a" -eq "$b" ])。
-
case 语句
:用于多值匹配,格式为
case 变量 in "值1") 语句1;; "值2") 语句2;; *) 默认语句;; esac,输入值匹配对应分支,*匹配所有未定义值。
(六)循环语句
表格
| 循环类型 | 语法格式 | 示例 | | — | — | — | | for 循环 | for ((初始化;条件;增量)); do 语句;done | for ((n=0;n<3;n++)) → 输出 n=0、1、2 | | while 循环 | while 条件;do 语句;done | n=0; while [${n} -lt 2 ] → 输出 n=1、2 | | until 循环 | until 条件;do 语句;done | n=-2; until ((n>1)) → 输出 n=-1、0、1、2 |
- 循环控制:
continue跳过当前循环剩余部分,break直接退出循环。
(七)函数
-
定义格式
:
function 函数名(){ 语句; }(function 可省略)。 -
参数传递
:调用时直接跟参数(如
fun 2 1),函数内用 $1、$2 接收参数。 -
返回值
:用
return 数值指定返回值,通过$?获取(如函数 return 3,echo $? 输出 3)。
关键问题
问题 1(基础操作):Bash 脚本的创建与执行有哪两种方式?核心区别是什么?
答案:两种执行方式及核心区别如下:① 赋权运行:先通过 chmod 777 脚本名.sh 赋予执行权限,再用 ./脚本名.sh 执行,核心区别是改变了文件本身的权限,后续可直接重复执行;② 临时运行:用 . ./脚本名.sh 执行,核心区别是无需修改文件权限,仅当前会话临时生效,适合测试脚本是否正常运行,不会改变文件的权限属性。
问题 2(语法细节):Bash 中变量的引用为什么推荐用 ${变量名} 形式,而非直接用 $ 变量名?请举例说明。
答案:推荐用 ${变量名} 形式的核心原因是避免在长字符组合中出现变量识别错误。例如:定义变量 str="abc",若想输出 “abc1”,用 ${str}1 会正确识别变量 str,输出 “abc1”;而直接用 $str1 会被误判为变量 str1(未定义,无输出),导致结果不符合预期。${变量名} 能明确界定变量的边界,确保解释器正确识别变量,尤其适用于变量与其他字符拼接的场景。
问题 3(逻辑应用):Bash 中 while 循环与 until 循环的核心区别是什么?分别适合什么场景?
答案:核心区别在于循环触发条件相反:① while 循环:满足条件时执行循环(条件为真则持续循环,条件为假时退出),适合已知循环终止条件的场景(如循环次数固定、达到某个数值停止),例如 n=0; while [ ${n} -lt 2 ] 表示 n 小于 2 时循环,直到 n≥2 退出;② until 循环:不满足条件时执行循环(条件为假则持续循环,条件为真时退出),适合未知循环次数、仅知道终止条件的场景(如等待某个状态变为真),例如 n=-2; until ((n>1)) 表示 n 不大于 1 时循环,直到 n>1 退出。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:网络安全直通车 guowei guowei《什么是Bash》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论