一、Shell编程理论和运用
1、程序的编程风格和执行模式
- 编程风格(Programming Style)
-
- 过程式编程:以指令为中心,来进行写程序,数据服务于指令。(bash shell) C
-
-
- 以指令为中心,程序的逻辑由一系列顺序执行的指令组成 。
- 数据仅服务于这些指令的执行过程
- 典型的例子包括Bash Shell编程和C语言
- 程序的结构主要由函数或者代码块来定义,数据和处理逻辑交织在一起。
-
-
- 对象式编程:以数据为中心,考虑先如何组织数据,指令服务于数据。 C# C++ JAVA PYTHON
-
-
- 以数据为中心,程序的设计主要关注如何组织和管理数据,而指令则服务于数据。
- 典型的例子包括C++、Java、Python等面向对象编程语言。
- 程序的结构由对象和类来定义,数据和处理逻辑被封装在对象内部,通过方法来操作数据。
-
- 执行模式(Execution Mode)
-
- 计算机的指令执行方式:
-
-
- 在计算机中,程序最终会被编译成机器指令,计算机按照这些指令顺序执行,完成特定任务。
- shell程序 (调用二进制程序 解释执行) 调用命令文件执行程序 ---> shell解释器去解释执行
- 程序的执行方式——计算机:二进制指令
-
-
- 编程语言的执行方式
-
-
- 编译型语言:如C、Java,在程序运行前先被编译成机器码,然后才能执行。
-
-
-
-
- 编译:高级语言-->编译器-->目标代码 C JAVA
-
-
-
-
- 解释型语言:如Python、Shell脚本,在运行时逐行解释执行,不需要预先编译成机器码。
-
-
-
-
- 解释:高级语言-->解释器-->机器代码 shell php ruby python
-
-
-
- shell编程的执行模式
-
-
- 顺序执行:按照脚本文件中的指令顺序依次执行。
- 循环执行:通过循环结构实现某些指令的重复执行,例如for循环、while循环。
- 选择执行:通过条件判断语句实现不同情况下的不同指令执行路径,例如if-else语句、case语句。
-
2、shell编程的结构
- Shell编程是一种通过编写Shell脚本来实现自动化任务的方式
- bash shell 核心中心就是调用指令(堆命令,严重依赖当前环境)
- Shell编程的结构
-
- 调用指令:
-
- Shell脚本的核心功能是调用各种命令来执行特定的任务。
- Shell脚本通过执行一系列的命令来实现预期的功能,这些命令可以是系统命令、Shell内置命令或者其他可执行程序。
-
- 变量和数组:
-
- Shell脚本中可以定义和使用变量,用于存储数据或者命令的输出结果。
- 数组则是一种特殊的变量类型,可以存储多个数值或者字符串。
-
- 表达式:
-
- Shell脚本可以包含各种表达式,用于进行数学运算、字符串操作、逻辑判断等操作。
-
- 语句:
-
- Shell脚本由一系列的语句组成,包括赋值语句、条件语句、循环语句、函数定义等。这些语句用于控制程序的流程和执行逻辑。
- Shell脚本的概念:
-
- Shell脚本是一种文本文件,后缀名以.sh为结尾。它包含了一系列的Shell命令和语句,用于完成特定的任务。
- 结构和格式:
-
-
- 开头通常会包含一个shebang(#!)行,指定了脚本的解释器路径, 脚本声明
- 例如#!/bin/bash表示使用Bash解释器执行脚本。
- 接下来是一系列的命令和语句,按照顺序执行以完成特定的任务。
-
-
- 脚本的执行:
-
-
- 脚本文件需要具有执行权限才能运行,可以使用【chmod +x script.sh】命令给脚本添加执行权限。
- 通过执行脚本文件,可以将其中的命令按照顺序执行,从而完成各种自动化任务。
-
-
- 结合控制语句:
-
-
- Shell脚本可以使用各种控制语句,如条件语句(if-else)、循环语句(for、while)、函数等,来实现复杂的逻辑操作和流程控制。
-
-
- Shell脚本的编写需要熟悉各种命令、语法和语句结构,合理利用这些特性可以高效地完成各种自动化任务。
3、脚本的应用场景
- 脚本的概念
-
- 将要执行的命令按照顺序保存到一个文本中
- 给文件相应的权限即可执行
- 结合控制语句可以完成复杂操作
- 脚本的应用场景
-
- 重复任务处理:
- 批量事务处理:
- 自动化运维:
-
-
- 在服务器运维领域,脚本被广泛用于自动化部署、配置管理、日志监控、故障处理等方面,提高了运维效率和系统稳定性。
-
-
- 定期任务执行:
-
-
- 通过编写定时任务脚本,可以实现定期执行特定的任务,如数据备份、日志清理、定时报告生成等。
-
-
- 服务器运行监控:
-
-
- 脚本可以编写用于监控服务器的运行状态、资源利用率、服务运行状态等,及时发现并处理问题,确保服务器的稳定运行。
-
- 脚本的结构——脚本声明+注释(解释信息)+可执行语句
-
- 脚本声明:
-
-
- 在脚本的开头通常会包含一个shebang(#!)行,用于指定脚本的解释器路径
- 例如#!/bin/bash表示使用Bash解释器执行脚本。
-
-
- 注释(解释信息):
-
-
- 注释用于解释脚本的作用、使用方法、作者信息等,提高脚本的可读性和可维护性。
-
-
- 可执行语句:
-
-
- 包括一系列的命令和语句,用于完成脚本的预期功能。这些语句可以是系统命令、Shell内置命令、函数调用等。
-
4、Shell程序和Python程序的执行
- Shell程序的执行可以通过以下方式
-
- 交互式shell环境:
-
-
- 用户可以直接在shell中输入命令行来与系统交互,执行各种操作。这种方式下,用户输入的每条命令都会立即执行并显示结果。
-
-
- 执行脚本:
-
-
- 用户可以编写一个包含一系列shell命令的脚本文件,然后通过shell解释器执行该脚本文件。
- 在执行脚本时,可以使用相对路径(例如./script.sh)或绝对路径(例如/path/to/script.sh)来指定脚本文件的位置。
-
-
- 命令:
-
-
- 用户可以直接在命令行中输入bash或sh命令,然后在shell环境中执行各种操作。
- 这种方式下,用户可以通过交互式方式输入命令,也可以通过脚本文件的方式执行一系列命令。
-
-
- source命令:
-
-
- source命令用于在当前shell环境中执行指定的shell脚本文件,并将其中的命令和变量直接应用于当前的shell环境。
- 与直接执行脚本不同,source命令执行的脚本文件中的内容会直接影响当前的shell环境,而不是在一个新的子shell中执行。
-
-
- 【.】(点号)命令:
-
-
- 与source命令类似,.(点号)命令也用于在当前shell环境中执行指定的shell脚本文件,并将其中的命令和变量直接应用于当前的shell环境。
- 它的作用与source命令几乎相同,但语法上略有不同。
- 这两种只在当前shell环境生效,重读授权表或者配置文件,一般用于shell程序内部的调用文本的I/O流
-
-
- bash的单步执行:
-
-
- 用户可以使用【bash -x】命令来以单步执行的方式运行脚本,这在脚本调试时非常有用。【bash -n】命令用于检查shell脚本的语法是否有错误,但不执行脚本。
-
5、变量的概念和运用
- 变量的概念和运用
-
- 变量是一段内存空间。在Shell编程中用于存储各种类型的数据,例如字符串、数字和命令输出等
- Shell引用:
-
-
- 在Shell中,使用单引号【''】和双引号【""】来引用变量
- 单引号为强引用,变量替换不会进行
- 双引号为弱引用,能够执行变量替换
- 反引号【````】(反引号)用于命令替换,引用命令的执行结果。
-
-
- 变量替换:
-
-
- 使用${变量名} 语法进行变量替换
- 通常情况下大括号可以省略。如果变量名后面要跟非小写字符串(包括大小字符串)、数字或下划线,那么变量名就一定要用大括号包起来。
-
-
- 变量的赋值:
-
-
- 变量名=值的语法进行赋值,中间不要有间隔空格。
- (注意,变量在赋值时不能再前面带$。)
-
-
- 变量名命名只能包含字母、数字和下划线,并且不能以数字开头、变量名区分大小写、尽量能见名知义
- 定义变量
-
- 本地变量:只对当前shell进程有效,对其子shell以及其他shell都无效。
-
-
- 定义变量:Var_Name="Value"
- 引用变量:${Var_Name},通常情况下大括号可以省略。
- 撤销变量:unset Var_Name
-
-
- 局部变量:只对某一部分有效。
-
-
- 定义变量:local Var_Name="Value"
-
-
- 环境变量:对其shell进程及其子shell有效(非系统自带不能跨终端)。
-
-
- 定义变量:
-
-
-
-
- export Var_Name="Value"
- Var_Name="Value"
- export Var_Name。
-
-
-
- 系统自带的环境变量可以通过【env】命令查看。
-
-
- 将系统自带的环境变量在当前shell更改,只能临时生效。若跨终端,不会生效,若退出登录,自动失效
-
- 系统环境变量根据读取顺序分为交互式登录和非交互式登录
-
- 交互式登录
-
-
- 发生在用户登录系统时,比如通过终端或SSH登录(系统会读取一系列的配置文件来设置用户的环境变量和执行特定的命令)
- 依次读取配置 /etc/profile ---> /etc/profile.d/xxx.sh ---> 当前登录家目录的.bash_profile ---> 当前登录用户的.bashrc ---> /etc/bashrc
-
-
-
-
- 【/etc/profile】系统级别的全局配置文件,对所有用户生效,提供系统范围的环境变量设置。
- 【/etc/profile.d/xxx.sh】系统级别的附加配置文件目录,通常包含多个以.sh为后缀的脚本文件,用于设置额外的环境变量。
-
-
-
-
-
- 【~/.bash_profile】当前登录用户的个人配置文件,对当前用户有效,用于设置个性化的环境变量和执行命令。
- 【~/.bashrc】当前登录用户的Bash配置文件,包含对shell的配置以及个性化设置,通常用于设置别名和自定义函数等。
- 【/etc/bashrc】系统级别的Bash配置文件,提供全局的Bash配置和设置,对所有用户生效。
-
-
-
-
- 在交互式登录中,系统会依次读取以上配置文件,如果存在同名文件,后面的文件会覆盖前面的配置,这是一个最小范围匹配原则,即最后加载的配置会生效。
-
-
- 非交互式登录
-
-
- 依次读取当前家目录的 .bashrc ----> /etc/bashrc ---> /etc/profile.d/xxx.sh
-
-
-
- 通常发生在运行脚本或执行命令时,而不是用户直接登录系统的情况
-
- 位置变量(shell特殊的变量)
-
- 位置变量用于处理传递给脚本的参数,其中$1表示第一个参数,依此类推。$1,......$n (需要传递参数)
- 当参数超过9个时,需要使用大括号${}来包裹,如${10}。
- 示例
#在Shell脚本中使用位置变量
#!/bin/bash
echo "The name of the script is: $0"
echo "The first argument is: $1"
echo "The second argument is: $2"
echo "The third argument is: $3"
echo "All arguments combined: $@"
#假设将上述脚本保存为script.sh
#然后执行命令./script.sh arg1 arg2 arg3,输出将会是:
The name of the script is: ./script.sh
The first argument is: arg1
The second argument is: arg2
The third argument is: arg3
All arguments combined: arg1 arg2 arg3
#在这个例子中,$0代表脚本本身的名称
#$1、$2和$3分别代表传递给脚本的第一个、第二个和第三个参数,
#$@表示所有的参数。
-
- 练习1 随机从系统找两个文件,判断这两个文件的文件的内容类型
#Shell脚本,随机选择系统中的两个文件,并使用file命令来判断这两个文件的类型:
#!/bin/bash
# 随机选择系统中的两个文件
file1=$(find / -type f -print | shuf -n 1)
file2=$(find / -type f -print | shuf -n 1)
# 判断文件类型并输出结果
echo "第一个文件 $file1 的类型是:"
file "$file1"
echo ""
echo "第二个文件 $file2 的类型是:"
file "$file2"
#将这个脚本保存为check_file_types.sh,然后给予执行权限并执行它
chmod +x check_file_types.sh
./check_file_types.sh
- 特殊变量:
-
- 【$0】表示脚本名称本身。
- 【$?】表示上一条命令的执行状态,0表示成功,1-255表示失败。
- 【$#】表示所有参数的个数。
- 【$*】表示所有参数列表。
- 案例:随机从系统找两个文件,显示出文件的内容类型,并将脚本本身的文件名和文件类型显示出来
#Shell脚本,实现随机从系统中找两个文件,显示出它们的文件类型
#!/bin/bash
# 随机选择系统中的两个文件
file1=$(find / -type f -print | shuf -n 1)
file2=$(find / -type f -print | shuf -n 1)
# 判断文件类型并输出结果
echo "第一个文件 $file1 的类型是:"
file "$file1"
echo ""
echo "第二个文件 $file2 的类型是:"
file "$file2"
echo ""
# 显示脚本本身的文件名和文件类型
echo "脚本本身的文件名和文件类型是:"
file "$0"
#将这个脚本保存为check_file_and_script_types.sh,然后给予执行权限并执行它:
chmod +x check_file_and_script_types.sh
./check_file_and_script_types.sh
二、Linux特殊权限管理
- Linux特殊权限管理涉及到SUID、SGID和Sticky Bit这三种特殊权限。这些权限可以在文件或目录上设置,以实现特定的功能和安全需求。
1. SUID概念
-
- 用于在执行文件时临时提升用户权限
-
-
- 当SUID权限被设置在一个可执行文件上时,该文件在执行时会以文件属主的权限来运行,而不是以执行者的权限来运行。
- 例如,如果一个普通用户需要执行一个只有超级用户才能执行的命令,但是系统管理员不想给予该用户超级用户的权限,那么可以将该命令的SUID权限设置为属主权限,这样该用户在执行该命令时就能够以超级用户的权限来执行。
-
-
- 如何将一个文件设置为SUID权限
-
-
- chmod u+s /path/to/executable_file
-
-
- 如何展示
-
-
- 当文件具有SUID权限时,如果属主有执行权限,则x权限位会被替换为s;
- 如果属主没有执行权限,则x权限位会被替换为S。这样在文件列表中,你会看到S代表了SUID权限
-
-
- 注意:SUID权限有风险,谨慎使用
2. SGID
-
- 概念: 允许在文件或目录上设置,以确保文件或目录的执行者以文件所属组的身份来执行
- 作用:
-
-
- 在文件级别:当一个用户执行了拥有SGID权限的可执行文件时,该用户的有效组会自动变成文件的所属组。
- 在目录级别:当一个用户创建了拥有SGID权限的目录,并在该目录中创建文件时,新文件将继承目录的所属组,而不是创建者的基本组。
-
-
- 如何添加SGID权限: 使用chmod命令,并在权限部分添加g+s选项。
- 示例:
-
-
- 设置文件的SGID权限:chmod g+s /path/to/file
- 设置目录的SGID权限:chmod g+s /path/to/directory
-
-
- 展示方式:
-
-
- 如果文件或目录的属组有执行权限,则SGID权限会以小写字母"s"来表示
- 如果属组没有执行权限,则以大写字母"S"表示。
-
3. sticky(粘滞位属性)
-
- 概念: Sticky Bit位主要用于目录。当在一个目录上设置了Sticky Bit位后,对于该目录中的文件,只有文件的所有者、目录的所有者或者root用户可以删除或移动这些文件。
- 作用:
-
-
- 在目录级别:当目录拥有了Sticky Bit位后,即使其他用户对该目录有写权限,也不能删除或移动不属于自己的文件。
- 这种行为通常用于一些共享目录,例如 /tmp,以确保所有用户都能在其中创建文件,但只能删除自己创建的文件。
-
-
- 设置方式: 使用chmod命令,并在权限部分添加o+t选项。
- 示例:
-
-
- 设置目录的Sticky Bit权限:chmod o+t /path/to/directory
-
-
- 展示方式:
-
-
- 如果目录的其他人权限中有执行权限,则Sticky Bit权限会以小写字母"t"来表示
- 如果没有执行权限,则以大写字母"T"表示。
-
4. acl权限扩展控制
-
- 概念:
-
-
- ACL是一种扩展权限控制方式,允许在文件或目录上定义一组用户或组的权限,以便更精确地控制文件和目录的访问。
- 不用更改原有的属主属组其他人的权限,属于文件的额外的权限
-
-
- 作用:
-
-
- ACL允许用户在不更改文件或目录的属主、属组和其他人权限的情况下,为特定用户或组分配额外的权限。
- 这样可以实现更细粒度的权限控制,例如,允许某个特定用户或组读取、写入或执行特定文件或目录。
-
-
- 命令:
-
-
- 【getfacl】用于查看文件或目录的ACL权限列表。
- 【setfacl】 用于设置文件或目录的ACL权限。
-
-
- 设置方式: 使用setfacl命令来设置ACL权限,可以为指定用户或组添加或删除特定权限。
- 示例:
-
-
- 设置ACL权限:setfacl -m u:wang:rw /path/to/file
- 撤销ACL权限:setfacl -x u:username /path/to/file
- 撤销所有ACL权限:setfacl -b /path/to/file
-
-
- 展示方式: 如果文件或目录有ACL权限,则会在原有权限标识符后面添加一个加号(+)来表示。例如,-rw-r--r--+。
5. 文件特殊属性和其他特殊权限
- 文件的特殊属性和其他特殊权限是用于增强文件安全性和稳定性的机制
-
- 通过设置文件的特殊属性和其他特殊权限,管理员可以提高文件的安全性和稳定性,防止误操作或恶意修改文件。这些特殊属性通常用于保护关键文件或日志文件,确保其完整性和可靠性。
-
- i(immutable)属性:
-
-
- 使用【chattr +i filename】命令可以将文件设置为不可修改的状态。
- 一旦文件被设置了i属性,就无法对其进行删除、重命名、更改内容,也无法为其创建或删除硬链接。
- 只有root用户可以使用【chattr -i filename】命令来解除i属性。
-
-
- a(append-only)属性:
-
-
- 使用【chattr +a filename】命令可以将文件设置为只能追加内容的状态。
- 一旦文件被设置了a属性,就无法对其进行删除、重命名、更改内容,只能在文件末尾追加内容。
- a属性通常用于日志文件,以防止非授权用户对文件进行篡改。
- 只有root用户可以使用【chattr -a filename】命令来解除a属性。
-
-
- 显示特定属性:
-
-
- 使用【lsattr】命令可以显示文件的特殊属性。
- 如果文件具有i属性或a属性,lsattr命令将在权限列表中显示对应的标识符。
-
6. selinux标签
- SELinux(Security-Enhanced Linux)是一种 Linux 内核安全模块,用于实施访问控制安全策略。
-
- SELinux会为文件、目录和其他对象分配安全上下文标签,用以标识它们的安全策略和访问权限
- 实施了严格的访问控制机制,提高了系统的安全性和稳定性
-
- SELinux上下文标签:
-
-
- SELinux为每个文件、目录和进程分配安全上下文标签,用于定义对象的安全策略和访问权限。
- 标签由多个部分组成,通常包括用户、角色、类型和安全级别等信息。
-
-
- 这些标签以.结尾,通常显示在文件权限列表的末尾
-
-
- 例如 -rw-r--r--. 1 root root 164 4月 26 23:20 kaoshi.py
- 描述了一个属主为 root,属组为 root,权限为 -rw-r--r--,大小为 164 字节,链接数为 1,最后修改时间为 4月26日23时20分的文件 kaoshi.py。
-
-
- 安全上下文标签的组成部分:
-
-
- 用户(user): 对象的所有者或创建者。
- 角色(role): 定义了对象如何与系统进行交互的角色。
- 类型(type): 定义了对象的类型和用途,如文件、目录、套接字等。
- 安全级别(level): 定义了对象的安全级别,通常用于多级安全(MLS)策略中。
-
-
- SELinux策略管理:
-
-
- SELinux策略由策略管理器(如semanage、semodule等)进行管理和配置。
- 管理员可以使用这些工具来调整文件、目录和进程的安全上下文,以满足安全要求。
-
-
- SELinux标签的作用:
-
-
- 根据对象的安全上下文标签,SELinux会强制执行访问控制规则,限制进程和用户对对象的访问权限。
- 通过正确配置和管理SELinux标签,可以提高系统的安全性,并防止恶意程序对关键文件和目录的未授权访问和修改。
-