首先来介绍Bash的基础知识。
Bash(Bourne Again SHell)是Linux和Mac OS X等系统中默认的命令行解释器(shell)。它用于执行命令、运行脚本以及自动化任务。
我们将从以下几个方面介绍:
Bash的基本概念
变量和参数
条件判断
循环
函数
输入输出重定向
管道
脚本调试
由于内容较多,我们将逐步展开。
Bash的基本概念
Bash是一个命令解释器,它读取用户输入的命令并执行。
Bash脚本是一个包含一系列命令的文本文件,通常以.sh为扩展名。
脚本的第一行通常是#!/bin/bash,指定解释器。
变量和参数
变量定义:变量名=值(注意:等号两边不能有空格)
使用变量:$变量名 或 ${变量名}
位置参数:$0(脚本名),$1(第一个参数),$2(第二个参数)…
特殊变量:
$#:参数个数
$@:所有参数,每个参数用双引号括起
$*:所有参数,作为一个整体
$?:上一个命令的退出状态
条件判断
条件判断有两种形式:
test 条件
或 [ 条件 ] (注意:括号前后有空格)更现代的写法是[[ 条件 ]](支持更多特性,如模式匹配)
条件判断常用于if语句和循环中。
循环
for循环
while循环
until循环
函数
定义函数:function 函数名() { 命令; }
调用函数:函数名 参数1 参数2 …
输入输出重定向
:输出重定向(覆盖)
:输出重定向(追加)
<:输入重定向
2>:错误重定向
管道
- 将一个命令的输出作为另一个命令的输入:命令1 | 命令2
脚本调试
- 使用-x参数运行脚本,可以显示每个命令及其参数。
下面我们通过一个简单的例子来展示这些概念。
示例脚本:example.sh
注意:在编写脚本时,给变量加上双引号以防止空格引起的错误,是一个好习惯。
Bash 基础全面介绍
一、Bash 是什么?
Bash(Bourne Again SHell)是 Linux/Unix 系统中最常用的命令行解释器,也是 macOS 的默认 shell。它是:
- 一个命令处理器:解析和执行用户输入的命令
- 一个脚本语言:用于编写自动化脚本
- 开源免费:GNU 项目的一部分
二、基本语法和结构
1.命令格式
command[选项][参数]- 选项通常以
-或--开头 - 参数是命令操作的对象
- 示例:
ls -l /home
2.脚本基础
#!/bin/bash # shebang行,指定解释器# 这是注释echo"Hello, World!"# 打印输出三、变量操作
1.变量定义和使用
name="Alice"# 定义变量(无空格)echo$name# 使用变量echo${name}# 推荐使用大括号echo"Hello,$name"# 字符串中使用# 只读变量readonlyPI=3.14# 删除变量unsetname2.特殊变量
#!/bin/bashecho"脚本名:$0"echo"第一个参数:$1"echo"参数个数:$#"echo"所有参数:$@"echo"所有参数(一个字符串):$*"echo"进程ID:$$"echo"退出状态:$?"四、字符串操作
str="Hello World"# 获取长度echo${#str}# 提取子串echo${str:0:5}# Helloecho${str:6}# World# 替换echo${str/World/Bash}# Hello Bash# 大小写转换str="hello"echo${str^^}# HELLO(转大写)echo${str^}# Hello(首字母大写)str="WORLD"echo${str,,}# world(转小写)五、数组操作
# 定义数组fruits=("apple""banana""cherry")# 访问元素echo${fruits[0]}# appleecho${fruits[@]}# 所有元素# 数组长度echo${#fruits[@]}# 元素个数echo${#fruits[0]}# 第一个元素长度# 添加元素fruits+=("orange")# 删除元素unsetfruits[1]# 遍历数组forfruitin"${fruits[@]}";doecho"Fruit:$fruit"done六、条件判断
1.if 语句
# 基本格式if[condition];thencommandselif[condition];thencommandselsecommandsfi# 示例if[$age-ge18];thenecho"成年人"elseecho"未成年人"fi2.测试运算符
# 数值比较[$a-eq$b]# 等于[$a-ne$b]# 不等于[$a-lt$b]# 小于[$a-gt$b]# 大于[$a-le$b]# 小于等于[$a-ge$b]# 大于等于# 字符串比较[$str1=$str2]# 相等[$str1!=$str2]# 不相等[-z$str]# 为空[-n$str]# 非空# 文件测试[-ffile]# 是普通文件[-ddir]# 是目录[-epath]# 存在[-rfile]# 可读[-wfile]# 可写[-xfile]# 可执行3.case 语句
case$OSin"Linux")echo"Linux系统";;"Darwin")echo"macOS系统";;"Windows")echo"Windows系统";;*)echo"未知系统";;esac七、循环结构
1.for 循环
# 遍历列表foriin12345;doecho"数字:$i"done# 遍历文件forfilein*.txt;doecho"处理文件:$file"done# C风格for循环for((i=0;i<10;i++));doecho"计数:$i"done2.while 循环
count=1while[$count-le5];doecho"计数:$count"((count++))done# 读取文件行whileIFS=read-rline;doecho"行内容:$line"done<file.txt3.until 循环
count=1until[$count-gt5];doecho"计数:$count"((count++))done八、函数
# 函数定义greet(){localname=$1# 局部变量echo"Hello,$name!"return0}# 调用函数greet"Alice"# 获取返回值greet"Bob"result=$?echo"函数返回值:$result"# 函数参数sum(){echo$(($1+$2))}sum1020# 输出 30九、输入输出重定向
# 输出重定向echo"内容">file.txt# 覆盖echo"内容">>file.txt# 追加# 输入重定向wc-l<file.txt# 错误重定向command2>error.log# 错误到文件command2>&1# 错误合并到标准输出command&>output.log# 所有输出到文件# 管道catfile.txt|grep"pattern"|wc-l十、高级特性
1.命令替换
# $(command) 格式current_date=$(date)echo"当前时间:$current_date"# `command` 格式(旧式)current_date=`date`2.算术运算
# 使用 $(( ))result=$((5+3*2))echo$result# 11# 使用 letlet"x = 5 + 3"let"y = x * 2"# 使用 expr(较旧)result=$(expr5+3)3.here document
cat<<EOF 这是多行文本 可以自由输入 直到遇到EOF标记 EOF# 忽略变量替换cat<<'EOF' $PATH 不会被展开 EOF4.进程替换
# 比较两个命令的输出diff<(lsdir1)<(lsdir2)# 处理命令输出whilereadline;doecho"处理:$line"done<<(find.-name"*.txt")十一、调试技巧
#!/bin/bash# 调试选项set-e# 遇到错误退出set-u# 使用未定义变量时报错set-x# 显示执行的命令set-opipefail# 管道中任一命令失败则失败# 调试函数debug(){echo"DEBUG:$@">&2}# 使用 trap 捕获信号trap'echo "脚本被中断"; exit 1'INTTERM十二、实用示例
1.备份脚本
#!/bin/bash# backup.shBACKUP_DIR="/backup"SOURCE_DIR="$HOME/documents"DATE=$(date+%Y%m%d_%H%M%S)# 创建备份tar-czf"$BACKUP_DIR/backup_$DATE.tar.gz""$SOURCE_DIR"# 检查备份是否成功if[$?-eq0];thenecho"备份成功: backup_$DATE.tar.gz"elseecho"备份失败">&2exit1fi2.系统监控脚本
#!/bin/bash# monitor.shLOG_FILE="/var/log/system_monitor.log"# 记录系统信息{echo"===$(date)==="echo"CPU使用率: $(top -bn1 | grep "Cpu(s)"|awk'{print $2}')%" echo "内存使用率:$(free-m|awk'/Mem:/ {print $3/$2*100}')%" echo "磁盘使用率:$(df-h/|awk'NR==2 {print $5}')" } >> "$LOG_FILE"3.批量文件处理
#!/bin/bash# batch_rename.sh# 批量重命名文件counter=1forfilein*.jpg;donew_name="photo_$(printf"%03d"$counter).jpg"mv"$file""$new_name"echo"重命名:$file->$new_name"((counter++))done十三、最佳实践
- 始终添加 shebang:
#!/bin/bash - 使用变量引用:
${var}而不是$var - 引用变量: 总是用双引号
"$var" - 检查命令返回值:
if command; then ... - 使用函数: 提高代码复用性
- 添加注释: 说明复杂逻辑
- 错误处理: 使用
set -euo pipefail - 使用版本控制: 管理脚本变更
十四、学习资源
- 官方文档: GNU Bash 手册
- 在线练习:
- Bash脚本教程
- Explain Shell
- 交互式教程:
- Bash Academy
- Learn Shell
总结
Bash 是一个强大而灵活的工具,掌握它能极大提高工作效率。建议从简单脚本开始,逐步实践更复杂的自动化任务,结合实际问题来学习。