当前位置: 首页 > news >正文

shell脚本基础详细学习(更新中)

shell简单介绍

Shell不仅仅是充当用户与UNIX或者localhost交互的角色,还可以作为一种程序设计
语言来使用。通过Shell编程,可以实现许多非常实用的功能,提高系统管理的自动化水平。
如果有一系列经常需要使用的命令,把它存储在一个文件里,shell可以读取这个文件
并顺序执行其中的命令,我们把这样的文件就叫shell脚本。shell脚本按行解释文件里的命令。

shell脚本的基本元素

对于一个基本的Shell程序来说,应该拥有以下基本元素:
1.声明:声明用哪个命令解释器来解释并执行当前脚本文件中的语句,一般写的解释器为
#!/bin/bash 。
2.命令:可执行语句,实现程序的功能。
3.注释:说明某些代码的功能,通过在代码中增加注释可以提高程序的可读性。

注释

1. 单行注释(#)

在 shell 脚本中,# 符号用于添加单行注释。从 # 开始,一直到这一行的末尾,所有内容都会被解释器忽略。其语法格式为:

# 这是一个单行注释
echo "Hello World"  # 这是行尾注释
2. 多行注释(: '...')

若要添加多行注释,可使用 : '注释内容' 这种形式。需要注意的是,这种注释方式不能嵌套使用。示例如下:

: '
这是一个多行注释
可以包含多行文本
'
echo "Hello World"

另外,还有一种利用未使用变量的替代方法:

if false; then
echo "第一行注释"
echo "第二行注释"
fi

单行注释是最常用的注释方式,而多行注释则适用于需要添加大块说明文字的场景。

3. 多行注释(:配合here document使用)

这是使用 Here Document( heredoc )创建注释块的方式,在 Shell 脚本中非常常见。以下是详细说明:

简单示例

:<<BLOCK
这是一个多行注释
可以包含任意文本,甚至包含 shell 命令、变量等
但不会被执行
BLOCK
  • ::是 Shell 内置命令,相当于 "空操作"(null command),不执行任何操作,仅返回状态码 0。
  • <<BLOCK:Here Document 标记,表示后续内容直到 BLOCK 结束都作为输入传递给 : 命令。
  • BLOCK:自定义的结束标记(可以使用任何合法标识符,如 EOFCOMMENT 等)。

关键点:

  1. 注释块可以包含任意内容

    :<<COMMENT
    这是有效的注释
    $变量不会被解析
    $(命令) 也不会被执行
    even if [ $x -eq 1 ]; then echo "not executed"; fi
    COMMENT
    
  2. 结束标记必须单独一行

    :<<EOF
    正确:EOF 在单独一行
    EOF:<<END
    错误:END 后面有空格或其他字符
    END  
    
  3. 标记名称建议大写:避免与变量名冲突(如 end 可能是已定义的变量)。

 shell脚本编写规范

(1)脚本文件名应见名知意,例如backup_mysql.sh
(2)文件开头指定脚本解释器 #!/bin/sh #!/bin/bash
(3)开头加版本特权等信息
# Date:创建日期
# Author:作者
# Mail:联系方式
# Function:功能
# Version:版本
(4)脚本中尽量不要用中文注释
  别吝啬添加注释,必要的注释方便自己别人理解脚本逻辑和功能;
  尽量用英文注释,防止本机或切换系统环境后中文乱码的困扰;
  单行注释,可以放在代码行的尾部或代码行的上部;
  多行注释,用于注解复杂的功能说明,可以放在程序体中,也可以放在代码块的开始部分。
(5)多使用内部命令
  常用的内部命令有:echo、eval、exec、export、read、shift、exit
1、echo是用于终端打印的基本命令,默认情况下,echo 在每次调用后会添加一个换行符
[root@kittod ~]# echo hehe
hehe
[root@kittod ~]# echo haha
haha
[root@kittod ~]# echo "Welcome to bash"
Welcome to bash
[root@kittod ~]# echo 'Welcome to bash'
Welcome to bash

2、上面的方法看起来效果一样,但是在某些场合会得到不一样的结果

[root@free ~]# echo 'the current directory is `pwd`'  单引号
the current directory is `pwd`
[root@free ~]# echo "the current directory is `pwd`"  双引号
the current directory is /root
[root@free ~]# echo "directory is `pwd`"
directory is /root
[root@free ~]# echo "`pwd`"
/root详细解释``作用
1. 命令替换的作用
借助命令替换,能够把命令的输出结果当作参数,嵌入到其他命令之中。就像这样:
echo "当前目录是 `pwd`"  # 先执行 pwd 命令,再把结果(如 /root)嵌入到字符串里
输出结果为:
当前目录是 /root2. 反引号(`)与美元符号加括号($(...))的对比
命令替换有两种表示方式:
传统写法:使用反引号(`命令`)
现代写法:使用 $(命令)
下面是这两种写法的对比示例:
echo "`date`"        # 输出当前日期时间(传统写法)
echo "$(date)"      # 输出当前日期时间(现代写法)
现代写法更加方便简洁,嵌套更加方便,反引号在命令替换中要使用其本身要用转义字符。反引号(`)的核心作用是**执行命令并获取结果**,进而实现动态参数的生成或者信息的嵌入。不过,在新的脚本中,更推荐使用 $(...) 这种写法,因为它更加清晰,还支持嵌套功能。[root@kittod ~]# echo "hehe;hehe"
hehe;hehe
[root@kittod ~]# echo hehe;hehe
hehe
-bash: hehe: command not found

简单示例:

[root@kittod ~]# echo -n i have a cat
i have a cat[root@kittod ~]#
[root@kittod ~]# echo -e i\thave\ta\tcat
ithavetatcat
[root@kittod ~]# echo -e "i\thave\ta\tcat"
i have a cat
[root@kittod ~]# echo "1 2 3"
1 2 3
[root@kittod ~]# echo -e "1\t2\t3"
1 2 3
[root@kittod ~]# echo -e "1 2 3"
1 2 3
#设置字体颜色
[root@kittod ~]# echo -e "\e[1;31m This is red test \e[0m"
This is red test
\e[1;31m 将颜色设置为红色, \e[0m 将颜色重置,使用时只需要更换颜色代码即可
颜色代码
重置 0
黑色 30
红色 31
绿色 32
黄色 33
蓝色 34
洋红 35
青色 36
白色 37
#设置背景颜色[root@kittod ~]# echo -e "\e[1;42m This is red test bg \e[0m"
This is red test bg
颜色代码
重置 0
黑色 40
红色 41
绿色 42
黄色 43
蓝色 44
洋红 45
青色 46
白色 47

 连续反斜杠加-e和默认的区别

1. 不带 -e 参数的 echo
bash
echo  today is\\\\\\ sunday
# 输出:today is\\\ sunday
规则:默认情况下,echo 会将连续的反斜杠按奇数 / 偶数处理:
偶数个反斜杠(如 \\、\\\\):每两个反斜杠合并为一个(\\ → \)。
奇数个反斜杠(如 \、\\\):最后一个反斜杠会转义其后的字符(若后无字符则保留)。
步骤解析:
bash
# 原始输入:today is\\\\\\ sunday
# 处理反斜杠:
# 1. \\\\ → \\(前四个反斜杠合并为两个)
# 2. \\ → \(最后两个反斜杠合并为一个)
# 最终输出:today is\\\ sunday2. 带 -e 参数的 echo
bash
echo -e today is\\\\\\ sunday
# 输出:today is\\ sunday
规则:-e 参数启用反斜杠转义功能,但 echo 会先按原始规则处理反斜杠,再应用转义:
偶数个反斜杠:合并后,若剩余偶数个,则继续两两合并;若剩余奇数个,则最后一个用于转义。
特殊转义符(如 \n、\t):会被解释为对应功能。
步骤解析:
bash
# 原始输入:today is\\\\\\ sunday
# 1. 原始反斜杠处理:
#    \\\\ → \\(前四个反斜杠合并为两个)
#    \\ → \(最后两个反斜杠合并为一个)
#    中间步骤:today is\\\ sunday# 2. 应用 -e 参数的转义:
#    \\\ → \\(前两个反斜杠合并为一个,最后一个转义空格失败,保留)
# 最终输出:today is\\ sunday3. 关键区别
参数	反斜杠处理逻辑	示例(输入 \\\\\\)	输出结果
无 -e	奇偶合并,奇数保留最后一个	\\\\\\ → \\\	\\\
-e	先奇偶合并,再转义特殊字符	\\\\\\ → \\\ → \\	\\
4. 常见误区
误解一:认为 -e 会直接解析原始反斜杠。
实际上,echo 会先处理反斜杠(合并 / 转义),再应用 -e 的特殊转义规则。
误解二:连续反斜杠在 -e 下总是成对解析。
只有合并后的奇数个反斜杠中的最后一个才会触发转义,例如:
bash
echo -e '\\\\\n'  # 输出:\\(前四个合并为两个,最后一个转义 \n)5. 如何正确输出多个反斜杠?
输出偶数个反斜杠:直接使用两倍数量的反斜杠。
bash
echo '\\\\'       # 输出:\\(默认模式)
echo -e '\\\\'     # 输出:\\(-e 模式)输出奇数个反斜杠:在 -e 模式下,需要额外的反斜杠来转义。
bash
echo -e '\\\\\\'   # 输出:\\\(前四个合并为两个,最后一个保留)总结
默认 echo:按奇偶合并反斜杠,奇数个保留最后一个。
echo -e:先处理反斜杠,再转义特殊字符(如 \n、\t)。
建议:若需精确控制反斜杠数量,优先使用单引号 ' 包裹字符串,并结合 -e 参数。

文本颜色样式设置代码详解

命令解析
echo -e "\e[1;31m This is red text \e[0m"
echo -e:启用对反斜杠转义字符的解释(如\e、\n等)
\e[1;31m:ANSI 转义序列,用于设置文本样式
\e:转义字符(ASCII 27,也可写作\033或\x1B)
[:控制序列引入符(CSI)
1:设置文本为粗体(可选参数)
31:设置文本颜色为红色(31 代表红色,32 为绿色,33 为黄色,依此类推)
m:设置属性命令
This is red text:实际显示的文本内容
\e[0m:重置所有文本属性,恢复默认样式
输出效果

当你运行这个命令时,终端会显示:

This is red text(实际显示为红色粗体)

然后恢复为默认文本样式。

其他颜色和样式选项

你可以通过修改转义序列中的数字来改变颜色和样式:

# 基本颜色代码
30: 黑色   31: 红色   32: 绿色   33: 黄色
34: 蓝色   35: 紫色   36: 青色   37: 白色# 背景颜色代码(40-47)
40: 黑底   41: 红底   42: 绿底   43: 黄底
44: 蓝底   45: 紫底   46: 青底   47: 白底# 样式代码
0: 重置    1: 粗体    4: 下划线   5: 闪烁    7: 反显

export命令详细解释

一、基本概念

环境变量 是 Shell 中存储的全局变量,可被当前 Shell 和所有子进程访问。而 局部变量 仅在当前 Shell 会话中有效,子进程无法继承。

export 的作用是:

  1. 将当前 Shell 中的局部变量转换为环境变量。
  2. 在定义变量时直接声明其为环境变量。

二、语法格式

export [变量名]=[值]     # 定义并导出新变量
export [变量名]          # 将已存在的局部变量导出为环境变量
export -f [函数名]       # 导出函数,使其在子Shell中可用
export -n [变量名]       # 取消变量的导出状态(使其变为局部变量)
export -p               # 显示所有已导出的环境变量

三、核心用法

bash -c 会创建一个全新的子 shell 进程来执行命令,该子 shell 与当前 shell 相互隔离。用于测试很方便。

1. 定义并导出变量
export NAME="Doubao"    # 定义并导出变量
echo $NAME              # 输出: Doubao# 在子Shell中验证
bash -c 'echo $NAME'    # 输出: Doubao(子Shell继承了环境变量)
2. 导出已存在的局部变量
AGE=25                  # 定义局部变量
export AGE              # 将局部变量导出为环境变量bash -c 'echo $AGE'     # 输出: 25
3. 导出函数
greet() { echo "Hello $1"; }
export -f greet         # 导出函数bash -c 'greet World'   # 输出: Hello World(子Shell可调用该函数)
4. 取消导出状态
export LANG=en_US.UTF-8
export -n LANG          # 取消LANG的导出状态
bash -c 'echo $LANG'    # 输出为空(子Shell无法访问)

四、与变量作用域的关系

变量类型定义方式作用域示例
局部变量NAME=value仅当前 ShellNAME=Doubao; echo $NAME
环境变量export NAME=value当前 Shell 及所有子进程export NAME=Doubao; bash -c 'echo $NAME'
全局变量.bashrc等文件中定义所有新启动的 Shell.bashrc中添加:export PATH="$PATH:/new/dir"

五、常见应用场景

1. 设置 PATH 路径
export PATH="$PATH:/home/user/bin"  # 添加自定义目录到PATH
2. 配置语言环境
export LANG=en_US.UTF-8             # 设置语言编码
3. 在脚本中使用环境变量
# script.sh
#!/bin/bash
echo "Hello $USER, today is $(date +%A)"# 执行脚本(继承当前环境变量)
export USER="Doubao"
./script.sh  # 输出: Hello Doubao, today is Friday
4. 临时测试环境变量
FOO=bar ./command     # 仅在执行command时设置FOO,执行后失效

六、注意事项

  1. 仅对当前 Shell 及子进程有效
    export 设置的变量只在当前 Shell 会话和其启动的子进程中生效。关闭终端后,设置会丢失。

  2. 永久生效需配置文件
    若要每次登录都生效,需将 export 命令添加到 Shell 配置文件中,如:

    # 对所有用户生效
    /etc/profile# 对当前用户生效
    ~/.bashrc  或  ~/.bash_profile
    
  3. 子 Shell 修改不影响父 Shell
    子进程中修改环境变量不会影响父进程:

    bash -c 'export TEST=123'  # 子Shell设置TEST
    echo $TEST                 # 父Shell中TEST仍为空
    

七、与其他命令的对比

命令作用示例
export设置环境变量,使其在子进程中可用export VAR=value
declare声明变量类型(如整型、数组等)declare -i NUM=100
readonly设置只读变量,不可修改或取消readonly PATH
set显示或设置 Shell 选项和变量set -x(开启调试模式)

总结

export 是 Shell 编程中用于管理环境变量的核心工具,通过它可以灵活控制变量的作用域,确保配置在不同进程间传递。合理使用 export 能帮助你更好地管理系统环境和编写可复用的脚本。

read命令详解

在 Bash 中,read 命令用于从标准输入(通常是键盘)读取用户输入,并将其赋值给一个或多个变量。它是交互式脚本、配置读取和数据处理的重要工具。以下是对 read 命令的详细解析:

基本语法

read [选项] [变量名1 变量名2 ...]
  • 功能:读取一行输入,按空格分割后赋值给对应变量。若变量数少于输入字段数,最后一个变量会包含剩余所有字段。
  • 示例
    read name age  # 输入 "Alice 25"
    echo "Name: $name, Age: $age"  # 输出: Name: Alice, Age: 25
    

常用选项

选项功能描述
-p "提示信息"显示提示信息,无需额外使用 echo
-t 超时秒数设置超时时间,超时后返回非零状态(需结合 -n 或 -s 使用)。
-s静默模式,不显示输入内容(适用于密码输入)。
-n 字符数读取指定数量的字符后立即返回,无需按回车。
-r禁用反斜杠 \ 的转义功能(原始输入)。
-d 分隔符使用指定字符作为输入结束标记(默认是换行符 \n)。

选项示例

  1. 带提示信息的输入

    read -p "请输入用户名: " username
    echo "欢迎, $username!"
    
  2. 密码输入(静默模式)

    read -s -p "请输入密码: " password
    echo  # 手动换行
    echo "密码已输入"
    
  3. 限时输入

    if read -t 5 -p "5秒内按Y确认: " answer; thenecho "你输入了: $answer"
    elseecho "超时!"
    fi
    
  4. 读取单个字符

    read -n 1 -p "按任意键继续..."
    echo  # 手动换行
    
  5. 原始输入(保留反斜杠)

    read -r path  # 输入 "C:\Users\Alice"
    echo "$path"  # 输出: C:\Users\Alice(而非 C:UsersAlice)
    

高级用法

  1. 从文件读取

    while read -r line; doecho "读取行: $line"
    done < filename.txt  # 逐行读取文件内容
    
  2. 读取特定分隔符的输入

    read -d '/' var1 var2  # 输入 "apple/banana"
    echo "Var1: $var1, Var2: $var2"  # 输出: Var1: apple, Var2: banana
    
  3. 读取数组

    read -a fruits  # 输入 "apple banana cherry"
    echo "第二个水果: ${fruits[1]}"  # 输出: banana
    

返回状态与错误处理

  • 成功:读取到有效输入时返回状态码 0
  • 失败
    • 超时(-t 选项)返回非零状态。
    • 读取到文件结束符(EOF,如按 Ctrl+D)返回非零状态。

示例:检查超时

if read -t 3 -p "快速回答: " answer; thenecho "回答: $answer"
elseecho "超时!" >&2exit 1
fi

注意事项

  1. 输入分割规则read 默认使用 IFS(内部字段分隔符,默认为空格、制表符、换行符)分割输入。如需自定义分割符,可临时修改 IFS

    IFS=',' read -r a b c <<< "1,2,3"
    echo "a=$a, b=$b, c=$c"  # 输出: a=1, b=2, c=3
    
  2. 空变量处理:若用户直接按回车,变量会被赋值为空字符串。可通过 read -e 启用 readline 编辑功能,提供默认值:

    read -e -p "请输入文件名 [default.txt]: " file
    file=${file:-default.txt}  # 使用默认值
    

总结

read 命令是 Bash 中处理用户输入的核心工具,通过灵活搭配选项(如 -p-s-t),可以实现从简单提示到复杂交互式脚本的各种需求。熟练掌握 read 能显著提升脚本的用户体验和功能完整性。

相关文章:

  • 仿真每日一练 | 有限元模态分析详解
  • 使用 ANSYS AEDT(单向耦合)进行高功率同轴射频滤波器的热分析
  • 介质访问控制(MAC)
  • 【PostgreSQL】不开启归档模式,是否会影响主从库备份?
  • 从零打造企业级Android木马:数据窃取与远程控制实战
  • leetcode0310. 最小高度树-medium
  • JAVA包装类
  • 在linux系统中,没有网络如何生成流量以使得wireshark能捕获到流量
  • 复合机器人案例启示:富唯智能如何以模块化创新引领工业自动化新标杆
  • kafka学习笔记(四、生产者、消费者(客户端)深入研究(三)——事务详解及代码实例)
  • Microsoft Azure DevOps针对Angular项目创建build版本的yaml
  • 编译型语言 vs 解释性语言 vs 编译解释语言
  • Missashe考研日记-day36(改版说明)
  • 昂瑞微高性能低功耗2.4G蓝牙芯片HS6621C支持BLE5.1协议主从一体支持语音采样苹果MFI认证寻物标签语音遥控
  • 如何通过C# 获取Excel单元格的数据类型
  • 【C++设计模式之Observer观察者模式】
  • Navicat BI 数据分析功能上线 | 数据洞察新方法
  • (leetcode) 力扣100 9.找到字符串中所有字母异位词(滑动窗口)
  • JAVA实战开源项目:健身房管理系统 (Vue+SpringBoot) 附源码
  • 常见标签语言的对比
  • 乘客被地铁厕所门砸伤,南京地铁:突然坏的,已和乘客沟通处理
  • 4月证券私募产品备案量创23个月新高,股票策略占比超六成
  • 上海市委常委会会议暨市生态文明建设领导小组会议研究基层减负、生态环保等事项
  • OpenAI任命了一位新CEO
  • 司法部:建立行政执法监督企业联系点,推行行政执法监督员制度
  • 美联储主席:不打算先发制人地降息,将继续观望