26、脚本编写与账户安全基础

脚本编写与账户安全基础

1. 条件表达式的使用

脚本语言支持多种类型的条件表达式,这些表达式能让脚本根据特定条件(通常是变量的值)执行不同的操作。常见的使用条件表达式的命令是 if ,它能让系统根据某个条件是否为真来执行两个操作中的一个。 if 关键字后的条件表达式放在方括号内,有多种形式。例如:
- -f file :如果 file 存在且为普通文件,则为真。
- -s file :如果 file 存在且大小大于 0,则为真。
- string1 == string2 :如果两个字符串的值相同,则为真。

条件表达式可以用逻辑与( && )或逻辑或( || )运算符组合。使用 && 时,运算符两边都为真,整个条件才为真;使用 || 时,只要运算符一边为真,整个条件就为真。

以下是一个使用条件表达式的代码片段:

if [ -s /tmp/tempstuff ]
  then
     echo “/tmp/tempstuff found; aborting!” 
     exit 
fi

这个代码片段会在 /tmp/tempstuff 文件存在时使脚本退出。 then 关键字标志着只有在条件为真时才会执行的一系列命令的开始, fi 标志着 if 块的结束。

条件表达式也可以使用 test 关键字,而不是方括号:

if test -s /tmp/tempstuff

还可以使用命令的返回值作为条件:

if [ command ]
  then
     additional-commands
fi

在这个例子中,只有当 command 成功完成时, additional-commands 才会运行。如果 command 返回错误代码, additional-commands 不会运行。

2. 条件表达式的扩展

条件表达式可以通过 else 子句扩展:

if [ conditional-expression ]
  then
     commands
  else
     other-commands
fi

这种形式的代码会根据 conditional-expression 的计算结果,执行 commands other-commands 。这在程序的某个部分需要根据特定条件执行不同操作时很有用。

如果有多个可能的结果,可以使用 case 语句:

case word in
  pattern1) command(s);;
  pattern2) command(s);;
  ...
esac

对于 case 语句, word 通常是一个变量,每个 pattern 是该变量的一个可能值。模式可以像文件名一样扩展,使用相同的通配符和扩展规则(例如 * 代表任意字符串)。每个命令集必须以双分号( ;; )结尾, case 语句整体以 esac 结尾。执行时, bash 会执行与 word 匹配的第一个模式关联的命令,然后跳转到 esac 语句后的行,中间的命令不会执行。如果没有模式匹配 word case 语句内的代码不会执行。如果需要默认条件,可以使用 * 作为最后一个模式。

3. 循环的使用

条件表达式有时会在循环中使用。循环是一种结构,它会让脚本重复执行相同的任务,直到满足特定条件(或直到某个条件不再满足)。

例如,以下脚本会播放目录中所有的 .wav 音频文件:

#!/bin/bash 
for d in `ls *.wav`; do
  aplay $d 
done

这里的 for 循环会为 ls *.wav 生成的列表中的每个项目执行一次。每个项目(文件名)会依次赋值给 $d 变量,并传递给 aplay 命令。

seq 命令在创建 for 循环时很有用,它可以生成一个从第一个参数开始到最后一个参数结束的数字列表。例如, seq 1 10 会生成 10 行,每行一个 1 到 10 之间的数字。可以使用 for x in seq 1 10 ` 让循环执行 10 次,每次迭代 x 的值递增。如果只传递一个参数给 seq`,它会将该数字作为结束点,起始点为 1;如果传递三个值,它会将它们解释为起始值、增量和结束值。

另一种循环是 while 循环,只要条件为真,它就会一直执行:

while [ condition ]
do
 commands
done

until 循环形式类似,但只要条件为假,它就会一直执行,直到条件变为真。

4. 函数的使用

函数是脚本中执行特定子任务的部分,可以从脚本的其他部分通过名称调用。函数的定义方式是在函数名后加上括号,并将组成函数的行用花括号括起来:

myfn() {
  commands
}

关键字 function 可以可选地放在函数名之前。无论哪种方式,函数都可以像普通的内部或外部命令一样通过名称调用。

函数有助于创建模块化脚本。例如,如果脚本需要执行六个不同的计算,可以将每个计算放在一个函数中,然后按顺序调用它们。以下是一个演示函数使用的脚本:

#!/bin/bash 

doit() {
  cp $1 $2 
} 

function check() { 
 if [ -s $2 ]
    then 
       echo “Target file exists! Exiting!”
       exit 
 fi 
} 

check $1 $2 
doit $1 $2

如果将这个脚本命名为 safercp ,假设 original.txt 存在而 dest.txt 不存在,可以这样使用:

$ ./safercp original.txt dest.txt
$ ./safercp original.txt dest.txt
Target file exists! Exiting!

第一次运行脚本成功,因为 dest.txt 不存在;第二次运行时,目标文件存在,脚本会终止并显示错误信息。

需要注意的是,函数不是直接按它们在脚本中出现的顺序运行的,只有在脚本的主体中调用时才会运行。

5. 设置脚本的退出值

通常,脚本的返回值与脚本调用的最后一个命令相同,即脚本返回 $? 。可以使用 exit 命令控制退出值,或在任何时候退出脚本。不使用任何选项时, exit 会立即终止脚本,返回通常的退出值 $? 。这在错误处理或因任何原因中止正在进行的操作时很有用。

如果给 exit 传递一个 0 到 255 之间的数值,脚本会终止并返回指定的值作为脚本自己的退出值。可以使用这个功能向可能调用自己脚本的其他脚本发出错误信号,但可能需要额外的代码来跟踪异常终止的原因。例如,可以设置一个变量(如 $termcause )来保存脚本终止的原因,在脚本开始时将其设置为 0,如果脚本检测到会导致终止的问题,将 $termcause 重置为非 0 值。退出时,确保将 $termcause 传递给 exit

exit $termcause
6. 账户相关知识

Linux 是多用户操作系统,提供了账户和组的功能。账户使多个用户可以共享一台计算机而不会相互造成太多麻烦,也使系统管理员能够跟踪谁在使用系统资源,以及谁在做不该做的事情。

6.1 账户特征

大多数账户特征在 /etc/passwd 文件中定义,该文件由冒号分隔的行组成,每行定义一个账户。例如:

rich:x:1003:100:Rich Blum:/home/rich:/bin/bash 

各字段信息如下:
| 字段 | 说明 |
| ---- | ---- |
| 用户名 | 账户的用户名是其最相关的特征,大多数 Linux 账户用户名由小写字母和偶尔的数字组成,下划线( _ )、破折号( - )和结尾的美元符号( $ )在某些发行版中也是有效的。 |
| 密码 | 用户账户通常由密码保护,登录计算机需要密码。大多数系统账户的直接登录被禁用,因此它们没有密码。 /etc/passwd 文件中的密码字段通常包含 x ,表示密码存储在 /etc/shadow 文件中。 |
| UID | 实际上,用户名只是计算机显示给人类的标签,计算机使用用户标识(UID)号来跟踪账户。UID 号从 0 开始(指 root 账户),在大多数发行版中,用户账户的 UID 号从 1000 及以上开始,较低的号码保留给系统账户。 |
| GID | 账户与一个或多个组相关联,组是账户的集合。每个账户通过组 ID(GID)号直接与一个主组相关联。 |
| 注释字段 | 通常包含用户的全名,也可以包含其他信息。 |
| 主目录 | 用户账户和一些系统账户有主目录,主目录是账户的“大本营”,通常属于该账户。使用波浪号( ~ )在文件名开头可以方便地访问用户的主目录。 |
| 默认 shell | 每个账户都关联一个默认 shell,在 Linux 中通常是 Bash( /bin/bash ),但用户可以更改。大多数非 root 系统账户将默认 shell 设置为 /usr/sbin/nologin /sbin/nologin 以增加安全性。 |

6.2 密码存储

/etc/passwd 文件由于历史原因必须对所有用户可读,因此存储密码存在风险。现在,密码存储在 /etc/shadow 文件中,普通用户无法读取该文件。一个典型的 /etc/shadow 条目如下:

rich:$1$E/moFkeT5UnTQ3KqZUoA4Fl2tPUoIc:16860:5:30:14:-1:-1:

各字段含义如下:
| 字段 | 说明 |
| ---- | ---- |
| 用户名 | 每行以用户名开头,通过用户名将该文件中的条目与 /etc/passwd 文件中的条目关联。 |
| 密码 | 密码以加盐哈希的形式存储,与实际密码没有明显相似之处。星号( * )或感叹号( ! )表示账户没有密码(即账户被锁定)。 |
| 上次密码更改日期 | 表示上次密码更改的日期,以自 1970 年 1 月 1 日以来的天数存储。 |
| 允许更改的天数 | 表示在允许更改密码之前的天数,用于防止用户按要求更改密码后又改回原密码。 |
| 需要更改的天数 | 表示自上次密码更改以来,需要再次更改密码的天数。 |
| 密码过期前的警告天数 | 如果系统配置为使密码过期,可以设置在过期日期临近时警告用户。 |
| 过期与停用之间的天数 | Linux 允许账户过期和完全停用之间有一个间隔。过期的账户要么不能使用,要么登录后需要立即更改密码。停用的账户密码被删除,需要系统管理员重新激活才能使用。值为 -1 表示此功能禁用。 |
| 过期日期 | 表示账户将过期的日期,以自 1970 年 1 月 1 日以来的天数表示。值为 -1 表示此功能禁用。 |
| 特殊标志 | 保留供将来使用,通常不使用或包含无意义的值。 |

对于与天数相关的字段,值为 -1 或 99999 通常表示相关功能已禁用。 /etc/shadow 文件通常以严格的权限存储,由 root 拥有,这对于影子密码系统的实用性至关重要,因为它可以防止非 root 用户读取文件并获取密码列表,即使是加盐哈希形式。相比之下, /etc/passwd 必须对普通用户可读,通常权限限制较少。

账户信息分散在多个配置文件中,如 /etc/passwd /etc/shadow /etc/group 等,用户文件可能位于用户的主目录或其他地方。因此,管理账户可能需要做的不仅仅是维护一两个文件,为此存在各种实用程序来帮助创建、管理和删除账户。

以下是一个简单的 mermaid 流程图,展示 if-else 条件判断的流程:

graph TD;
    A[开始] --> B{条件表达式是否为真};
    B -- 是 --> C[执行 commands];
    B -- 否 --> D[执行 other-commands];
    C --> E[结束];
    D --> E;

通过以上内容,我们了解了脚本编写中条件表达式、循环、函数的使用,以及如何设置脚本的退出值,同时也掌握了 Linux 系统中账户和密码存储的相关知识。这些知识对于 Linux 用户和管理员来说是非常重要的基础。

脚本编写与账户安全基础

7. 账户安全与管理的重要性

账户安全是 Linux 系统安全的重要组成部分。由于账户信息分散在多个配置文件中,且用户文件可能位于不同位置,管理账户需要综合考虑多个方面。例如,如果 /etc/shadow 文件的权限设置不当,非 root 用户可能会获取到加密后的密码信息,从而增加系统被破解的风险。

在管理账户时,需要注意以下几点:
- 定期检查账户信息 :查看 /etc/passwd /etc/shadow 文件,确保账户信息的准确性和安全性。例如,检查是否有异常的 UID 或 GID 分配,以及密码是否正确存储在 /etc/shadow 中。
- 及时更新密码策略 :根据系统的安全需求,调整 /etc/shadow 文件中的密码更改时间限制、警告天数等参数。例如,缩短密码需要更改的天数,增加密码的安全性。
- 合理分配账户权限 :根据用户的工作职责,为账户分配适当的权限。避免给予普通用户过高的权限,防止误操作或恶意行为对系统造成损害。

8. 脚本编写与账户管理的结合应用

在实际工作中,脚本编写可以与账户管理相结合,提高工作效率和系统的安全性。以下是一些常见的应用场景:

8.1 批量创建账户

可以编写一个脚本来批量创建账户,避免手动输入大量信息。以下是一个示例脚本:

#!/bin/bash

# 定义用户名列表
usernames=("user1" "user2" "user3")

# 循环创建账户
for username in "${usernames[@]}"
do
    useradd $username
    echo "账户 $username 创建成功"
done

在这个脚本中,我们定义了一个用户名列表,然后使用 for 循环遍历列表,使用 useradd 命令创建账户。

8.2 检查账户密码过期情况

可以编写一个脚本来检查账户密码的过期情况,并及时提醒用户更改密码。以下是一个示例脚本:

#!/bin/bash

# 获取所有用户的用户名
users=$(cut -d: -f1 /etc/passwd)

# 循环检查每个用户的密码过期情况
for user in $users
do
    passwd_info=$(chage -l $user)
    days_to_expire=$(echo "$passwd_info" | grep "Days until password expires" | awk '{print $NF}')
    if [ $days_to_expire -lt 7 ]
    then
        echo "用户 $user 的密码将在 $days_to_expire 天内过期,请及时更改"
    fi
done

在这个脚本中,我们首先使用 cut 命令从 /etc/passwd 文件中获取所有用户的用户名,然后使用 chage -l 命令获取每个用户的密码信息,提取密码过期的天数。如果过期天数小于 7 天,则输出提醒信息。

9. 总结与实践建议

通过本文的介绍,我们了解了脚本编写中的条件表达式、循环、函数的使用,以及如何设置脚本的退出值,同时也掌握了 Linux 系统中账户和密码存储的相关知识。为了更好地应用这些知识,以下是一些实践建议:

  • 多实践脚本编写 :通过编写不同类型的脚本,如文件处理脚本、账户管理脚本等,加深对脚本编写的理解和掌握。在编写脚本时,可以参考本文中的示例代码,结合实际需求进行修改和扩展。
  • 定期备份账户信息 :由于账户信息分散在多个配置文件中,定期备份这些文件可以防止数据丢失。可以使用 cp 命令或其他备份工具进行备份,备份文件可以存储在外部存储设备或远程服务器上。
  • 加强账户安全意识 :作为系统管理员或普通用户,要时刻保持账户安全意识。不随意泄露账户密码,定期更改密码,避免使用弱密码。同时,要注意查看系统日志,及时发现异常的账户登录行为。

以下是一个 mermaid 流程图,展示批量创建账户的流程:

graph TD;
    A[开始] --> B{定义用户名列表};
    B --> C{循环遍历用户名列表};
    C -- 是 --> D[使用 useradd 命令创建账户];
    D --> E[输出创建成功信息];
    E --> C;
    C -- 否 --> F[结束];

希望本文的内容能够帮助你更好地掌握脚本编写和账户管理的知识,提高 Linux 系统的使用效率和安全性。在实际应用中,要不断学习和实践,根据具体情况灵活运用这些知识。

基于实时迭代的数值鲁棒NMPC双模稳定预测模型(Matlab代码实现)内容概要:本文介绍了基于实时迭代的数值鲁棒非线性模型预测控制(NMPC)双模稳定预测模型的研究Matlab代码实现,重点在于通过数值方法提升NMPC在动态系统中的鲁棒性稳定性。文中结合实时迭代机制,构建了能够应对系统不确定性外部扰动的双模预测控制框架,并利用Matlab进行仿真验证,展示了该模型在复杂非线性系统控制中的有效性实用性。同时,文档列举了大量相关的科研方向技术应用案例,涵盖优化调度、路径规划、电力系统管理、信号处理等多个领域,体现了该方法的广泛适用性。; 适合人群:具备一定控制理论基础和Matlab编程能力,从事自动化、电气工程、智能制造等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于解决非线性动态系统的实时控制问题,如机器人控制、无人机路径跟踪、微电网能量管理等;②帮助科研人员复现论文算法,开展NMPC相关创新研究;③为复杂系统提供高精度、强鲁棒性的预测控制解决方案。; 阅读建议:建议读者结合提供的Matlab代码进行仿真实践,重点关注NMPC的实时迭代机制双模稳定设计原理,并参考文档中列出的相关案例拓展应用场景,同时可借助网盘资源获取完整代码数据支持。
UWB-IMU、UWB定位对比研究(Matlab代码实现)内容概要:本文介绍了名为《UWB-IMU、UWB定位对比研究(Matlab代码实现)》的技术文档,重点围绕超宽带(UWB)惯性测量单元(IMU)融合定位技术展开,通过Matlab代码实现对两种定位方式的性能进行对比分析。文中详细阐述了UWB单独定位UWB-IMU融合定位的原理、算法设计及仿真实现过程,利用多传感器数据融合策略提升定位精度稳定性,尤其在复杂环境中减少信号遮挡和漂移误差的影响。研究内容包括系统建模、数据预处理、滤波算法(如扩展卡尔曼滤波EKF)的应用以及定位结果的可视化误差分析。; 适合人群:具备一定信号处理、导航定位或传感器融合基础知识的研究生、科研人员及从事物联网、无人驾驶、机器人等领域的工程技术人员。; 使用场景及目标:①用于高精度室内定位系统的设计优化,如智能仓储、无人机导航、工业巡检等;②帮助理解多源传感器融合的基本原理实现方法,掌握UWBIMU互补优势的技术路径;③为相关科研项目或毕业设计提供可复现的Matlab代码参考实验验证平台。; 阅读建议:建议读者结合Matlab代码逐段理解算法实现细节,重点关注数据融合策略滤波算法部分,同时可通过修改参数或引入实际采集数据进行扩展实验,以加深对定位系统性能影响因素的理解。
本系统基于MATLAB平台开发,适用于2014a、2019b及2024b等多个软件版本,并提供了可直接执行的示例数据集。代码采用模块化设计,关键参数均可灵活调整,程序结构逻辑分明且附有详细说明注释。主要面向计算机科学、电子信息工程、数学等相关专业的高校学生,适用于课程实验、综合作业及学位论文等教学科研场景。 水声通信是一种借助水下声波实现信息传输的技术。近年来,多输入多输出(MIMO)结构正交频分复用(OFDM)机制被逐步整合到水声通信体系中,显著增强了水下信息传输的容量稳健性。MIMO配置通过多天线收发实现空间维度上的信号复用,从而提升频谱使用效率;OFDM方案则能够有效克服水下信道中的频率选择性衰减问题,保障信号在复杂传播环境中的可靠送达。 本系统以MATLAB为仿真环境,该工具在工程计算、信号分析通信模拟等领域具备广泛的应用基础。用户可根据自身安装的MATLAB版本选择相应程序文件。随附的案例数据便于快速验证系统功能性能表现。代码设计注重可读性可修改性,采用参数驱动方式,重要变量均设有明确注释,便于理解后续调整。因此,该系统特别适合高等院校相关专业学生用于课程实践、专题研究或毕业设计等学术训练环节。 借助该仿真平台,学习者可深入探究水声通信的基础理论及其关键技术,具体掌握MIMOOFDM技术在水声环境中的协同工作机制。同时,系统具备良好的交互界面可扩展架构,用户可在现有框架基础上进行功能拓展或算法改进,以适应更复杂的科研课题或工程应用需求。整体而言,该系统为一套功能完整、操作友好、适应面广的水声通信教学科研辅助工具。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
数据结构部分 -- 一、栈和队列 Stack && Queue 栈 - 结构图 alt 队列 - 结构图 alt 双端队列 - 结构图 alt 二、 链表 Linked List 单链表 - 结构图 alt 单项循环链表 - 结构图 alt 双向链表 - 结构图 alt 三、 树 基础定义及相关性质内容 - 结构图 alt - 另外可以参考浙江大学数据结构课程中关于遍历方式的图,讲的十分详细 alt 使用链表实现二叉树 二叉查找树 - 非空左子树的所有键值小于根节点的键值 - 非空右子树的所有键值大于根节点的键值 - 左右子树都是二叉查找树 补充 - 完全二叉树 - 如果二叉树中除去最后一层节点为满二叉树,且最后一层的结点依次从左到右分布,则此二叉树被称为完全二叉树。 - 满二叉树 - 如果二叉树中除了叶子结点,每个结点的度都为 2,则此二叉树称为满二叉树。 代码下载地址: https://pan.quark.cn/s/b48377ea3e78 四、 堆 Heap 堆满足的条件 - 必须是完全二叉树 - 各个父节点必须大于或者小于左右节点,其中最顶层的根结点必须是最大或者最小的 实现方式及条件 - 使用数组实现二叉堆,例如下图的最大堆,在数组中使用[0,100,90,85,80,30,60,50,55]存储,注意上述第一个元素0仅仅是做占位; - 设节点位置为x,则左节点位置为2x,右节点在2x+1;已知叶子节点x,根节点为x//2; - 举例说明: - 100为根节点(位置为1),则左节点位置为2,即90,右节点位置为3,即85; - 30为子节点(位置为5),则根节点为(5//2=2),即90; 根据上述条件,我们可以绘制出堆的两种形式 - 最大堆及实现 al...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值