shell脚本编程高级篇

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell脚本编程高级篇相关的知识,希望对你有一定的参考价值。

SHELL脚本编程进阶
循环执行:简单来说就是把一些指令重复循环。

循环代码具体的指令有三种: for , while , until其中for, while用的最多。
for循环

for 变量名 in 列表;do
循环体
done

关键字的帮助都是用help来查询。
for循环语法:在shell编程中 for,in,do,done。这些都是他的关键字,其中循环的指零就放在do和done之间。
WORDS决定了循环次数。
循环的次数由in 后面跟的WORDS(字符串)的数量决定。字符串的个数决定了do和done之间的指令执行的次数。

$:for认为是一个整体br/>$@:for认为是独立的参数
for循环逻辑:↓↓
:这条命令意思是,将i变量为1 22 33 等于说i同时等于这3个变量然后用到$i把变量显示出来第一次i就是1第二次i就是22第三次i就是333这就是for循环的逻辑。
:还可以使用花括号或字母一次性显示完。
for脚本编辑语法:,脚本意思是i变量为arg而$@是独立的一个整体执行为脚本后面跟123代表arg is 独立的123。
:这是重复创建10次用户的意思i变量为1..10这个范围
:这是让FILE变量为userlist.txt这个文件然后执行这个文件里有多少用户,在来循环多少次。
:不用创建脚本也可以在外执行for结尾必须使用;隔开done
:该脚本意思是先cd进入/data/test这个文件然后将FILE变量为里面所有的文件,然后PRE等于用sed挑选出 . 前面的文件,再用mv替换为 .log文件。
脚本也支持进程执行↓↓
:该命令意思是NETID变量等于172.16.128 。for HOSTID in 1..254让hostid循环1到254次。If(如果)ping是启动的就扔到垃圾堆/dev/null中去而且是并行执行&。Ping -c1是一秒,
最后wait命令 用来等待指令的指令,直到其执行完毕后返回终端。该指令常用于shell脚本编程中,待指定的指令执行完成后,才会继续执行后面的任务。
:脚本意思是先用变量语句$1是选取的参数-c然后 是执行并行任务,在用forUSER等于/data/name.txt的变量,这个文件里有多少需要创建的用户,再用if来判断,如果出货你在就显示为exist(存在),如果不存在这样的用户则创建用户useradd $SUER ,在用pass变量为随机的6为数。
在把密码丢进passwd.txt这个文件中去,不让密码显示所以就用了passwd --stdin 这是第一个脚本循环。 下来则是-r 删除。最后提示执行人员输入-c 或-r也就是创建或者删除
for循环嵌套
:脚本意思是i等于1到10的循环,然后j又是1到10 的循环,等于说是让i的1到10循环10次,最后显示
\C是代表不换行。
:可在脚本中加入多个并行执行进程,红框为一组。这是让ping通的地址丢到/data/ip.txt中去,然后短路或显示is up
:骚骚脚×××星
for循环第二种语法

(第二个条件为真就执行第三条件,直到第二个条件为假才停止循环。)

第二种语法逻辑:↓↓↓

for 两个小括号((里面有3个表达式))这3个实现的逻辑是这样的,在执行循环前先执行第一个表达式(循环还没有执行,就先执行他)。然后不管第一个指令成功或失败接着就判断第二个表达式是否为真,如果为真那就执行循环体,执行完循环体之后并没有退出循环,接着去执行第三个表达式,第三个表达式不论成功失败都会反过来再去判断第二个表达式是否为真,如果文字继续执行循环体,循环体执行完之后再去执行第三个表达式,然后反过头来再去判断第二个表达式是否为真。
等于说exp1 只执行一次后续在不执行。exp2就作为循环的判断条件,只有exp2为真的条件下才会执行,而且exp3始终都要执行知道循环结束退出。当exp2执行失败的时候整个循环执行结束。
第二种语法基础写法:
:这个脚本是将sum变量为0然后使用for的第二种语法,
i=1(第一个表达式)只出现一次等于给i一个变量i<=100(第二种表达式)作为循环的判断条件只有为假的时候才执行结束正好超过100就为假所以最多100 ,i++(第三种表达式)始终都要执行,直达循环结束退出。
然后再计算sum+=i意思是sum+(0+)=i
当然还支持变量。
:也可以不加$直接支持变量。
九九乘法表的第二种语法表示
:第一个条件i=1为第一个表达式所以只能出现一次,第二个表达式意思最多i只能到9,第三个表达式其中每次加1然后再执行第二个for循环,j也是同理。最后使用i和j的每次变量$I X $J 就是显示1x1到每次的9,$[J*I]这才是真正的乘法计算,然后echo \t选项是对其\c是不换行显示出来,有几个for就必须得加几个done。
:九九乘法表,这是让result变量为i乘j的和
:是用for来生成随机数,第一次i=0是第一个条件,然后第二个条件是小于10说明i只能循环10(0-9)每次增加1,然后N等于循环体,再打印出来\n换行,然后再通过if判断这里的 [ $i -eq 0 ] 是表示第一次循环的i=0那次条件的N循环体来作为判断条件MAX=$N是表示第一次i循环的那次随机MIN也是同理,
然后再else再开启第二次if判断,这的$N表示for那次的循环体随机数和第一次取值的i=0那次的MAX进行比较,比max大的则显示出来MIN也是同理。然后再打印出来。
:白色框。
While循环使用及原理

While循环用法更通用。更擅长于处理非数字循环。
While循环逻辑:while加循环条件,这个循环条件如果成立将执行循环体。循环体结束以后返回来在判断此条件是否成立,如果成立继续执行循环,直到某一次判断这条件不成立整个循环结束。 (为真继续执行循环,为假退出循环。 )
While语法:
:脚本意思是
Sum=0
i=1
然后通过while循环来进行判断,此时的$i就是1因为变量,而且只能小于大于100因为-le,这就是这个脚本的循环多少次的条件。
let(脚本里计算的命令) sum+等于一次累加i的值。
let i++ 让i一次累计加i的循环值。
done(脚本的结束命令)
echo sum=$sum这是打印sum=(sum这的sum是应用了上面sum+的变量)
:脚本意思先打印出随机数,MAX 和MIN都是那个数使用echo显示出来,然后再开始while循环i小于10等于从0到10循环10次而N等于$RANDOM等于说找出10个数据数因为N是循环体,则显示出10个随机,再使用if判断如果说10次随机里有一个最大的数大于MAX的那个随机数,则就是真的直接就显示MAX=$N因为N的数大于MAX,然后再进入第二个条件判断elif,找出最小的数i++等于i一次累加1。再使用echo打印出来。
:脚本意思是while true永久为真一直执行,kill 0信号是判断进程是否正常,!是取反如果不正常就为真执行systemctl restart 重启httpd服务。下面是生成日志文件 。
:while 做的9x9乘法表。i=1
脚本意思是i变量为1 然后利用while 循环 且小于等于9 j变量为1且小于等于i变量然后使用let做技术,让result变量为i乘j 最后在使用echo -e打印出来他们的含义且变量再一个环境内要用大括号包起来,在使用$result变量\t代表tab键\c代表换行然后i++和j++分别是一次增加一个。

Until循环

Until循环逻辑:
Until当执行条件为假的时候就不执行了。
循环控制

Continue和break还支持对嵌套循环的控制
Continue 是结束本次循环。
:该脚本是当i执行到第五次那一次循环就不执行直接跳过,直接进入下一次循环。因为continue直接结束第五次的循环
:该脚本的意思是i等于0且小于5一次增加1等于说i最多能循环5次,这是执行第二个循环,j=0且j<10然后一次加一,这是他的循环次数然后执行循环体,-eq 5是等于5说明循环五次但是j是0循环到五次只能到4,在if为真时就执行continue 2 对外层循环结束他的本次循环然后又判断最里面这个循环因为这是循环嵌套。所以结果为重复打印5次。因为i是循环5次

break :是结束整个循环。
:脚本意思以为i=0且小于10一次累加1然后再用if判断i等于第五次循环是否为真且i最多能到9所以这是真的,真的就执行break(结束整个循环体)循环到5次后面的循环整个结束。结果为

:break2是对第二层循环退出控制,当i看到j等于五次循环5次i最外层循环就结束,然后结束整个循环,只循环打印一次j的循环。
:break什么都不输默认为第一层,最里面层就为第一层,说这是当看见j循环了5次就退出,而i依旧循环到第10次i<10而j每次只能循环5次i显示完整个循环结束,

While read 能够实现逐行处理。利用read配合while就能实现读入一行处理一次。
:while配合read就是逐行处理,seq为10就是循环处理10让$line变量为前面的seq的值。

IP tables -vnL:查看防火墙。防火墙屏蔽了172.18.0.7这个IP地址
:这是将ip为172.18.146.73丢到防火墙里。

Shift这个命令可以将位置参数向左移动,每移动一次会把最左边的参数用后续的参数覆盖,一旦执行shift就会把前一个参数覆盖,第一个参数就没了,而后面参数的顺序依次往前2参数变一次类推。
:因为shift是从左往右依次进行处理,$1表示脚本创建好再外执行的执行完了就显示user is finished。
:这就是使用shift 一次执行创建用户。
:这是脚本后面啥都没有跟就什么都没有显示。

计划任务中的变量和我们在脚本中使用的变量是不一致的。
对于这种问题
:在执行crontab -e这个计划任务时,必须写上命令的PATH变量的绝对路径,
:which就能看见命令路径。
内部命令是不用写路径的
Select循环与菜单。

Select后面也是跟的变量名,而不是变量引用。不用加$。他的逻辑也是一种循环他会把in后面跟的列表自动的生成菜单,会把WORDS进行扩展生成一个一个的单词列表,然后生成的列表会进行打印,并且在每个单词的前面添加一个数字,等于说in 后面有多少个单词就会生成多少行,会自动按顺序打印。例图:↓↓通过输入对应的数字就可以实现使用那个数字的功能这个地方就要涉及到其他的变量,其中用户输入的这个数字就会存放在REPLY的这个变量中这是系统自带的变量,因为REPLY就是存放输入的东西,然而REPLY只是知道你输入了什么并不知道你输入的东西和上面有什么关系。还有个变量叫PS3它可以定义输入得提示信息↓↓

Select:该循环主要用于创建菜单,或者启用脚本的功能。
Select可以引用脚本实现以脚本开启另一个脚本功能。

Ps3(只能配合select):是一个变量,可以定义提示信息。

Case 和select是绝配,可以配合使用。
:case是用来判断后面跟$MENU依次根据上面显示的来判断。
该命令的意思是通过MENU的变量依次显示出上面的选项然后打印最后用quit来退出,不然这就是一个死循环,然后他并没有输入上面的就用*来提示选择错误最后用esac退出case要加$因为他不输入高级进阶脚本,不加的话无法正
常识别。
:PS2是多行从定项的提示符。这的\是转义的意思。

函数的介绍及使用
函数这个技术可以大大简化重复的动作,他的思想就是把我们日常要做的事一个小的功能用一个独立的一个语句块来实现,这个语句块就是多条shell脚本的集合,但是这个语句块就像是命名的别名一样。函数把一些shell脚本的程序写在一个语句块里面,给他取个函数名,然后用这个函数名来代表后面一大串指令。有了这个函数名以后直接就可以调用函数名就可以实现使用后面跟的指令及脚本程序。 函数将一些shell脚本写到一个语句块里面。类似于alias(别名)意思。而函数可以独立的放到准备的文件里的。可以不和脚本放在一起。将来引用这个函数对应的文件就可以了。
函数具体的实现及各种调用
函数首先需要去声明函数定义函数,函数的使用需要用到function(英译功能)这个关键字:用来实现函数的定义
函数的语法他有三种格式:
1:name () 写上函数名空格小括号,后面写定义
2:function关键字写上 然后函数名 对应的函数定义
表示函数开始。
表示函数结束。
? 函数由两部分组成:函数名和函数体
函数比较标志性的符号()
help function
? 语法一:
f_name ()
...函数体...

? 语法二:
function f_name
...函数体...

? 语法三:
function f_name ()
...函数体...

函数定义
脚本里对一个函数的调用
:该脚本表示了如何调用函数。脚本意思是,先将( :这是一个函数定义,这是一个函数名 )这一条命令放入到函数中$1是表示外面的第一个参数变量。而且必须是以数字开头和数字结尾的,然后再下文中使用read -p选项直接输入变量为SCORE,然调用is_digit这个函数来判断$ SCORE这个变量是否为数字,等于说判断用户是否输入的是数字。这的$ SCORE是上面read -p 的变量,而is_digit是调用了上面的函数名。来判断输入结果。
创建函数文件即调用。
函数文件里面专门负责只放函数。
先创建一个存放函数的文件我这创建的是function文件。
再将函数定义写进function这个文件中这就创建好了一个函数定义文件
在创建一个脚本:↓↓
. function 是直接调用了function这个文件里的函数。
以后觉得函数写的不满意不完善,即使修改也不影响其他的脚本使用,只需改一下function文件下的函数定义。
函函数文件中还可以支持变量↓↓

return值得使用及原理

return:将返回调用此函数的脚本本身。
return:必须放到函数里使用不能放到脚本。
return执行逻辑:当执行完以后结果为假,就会回到继续执行后续的脚本中。
:这输入的return是返回到了脚本本身而不是退出脚本
该脚本就是引用了函数中带return
:脚本意思使用 . function 文件中函数来进行判断,接着使用read -p 作为脚本起始于然你输出你的年龄(AGE),然后变量为AGE再使用( :这是function函数文件中的
一个函数块)等于说引用了这个函数块对$AGE进行判断是否是数字。接着使用while 判断输入的 $? 是否不等于0不等于零为真接着又调用is_digit函数块进行判断直达输入为数字才停止,以为不是数字为假而函数块中使用了return这个命令,return的逻辑当执行完以后结果为假,就会回到继续执行后续的脚本中,因为上面有while的不等于0判断为真就执行下面的循环体,一直循环直到输入了数字为假才会退出当前循环
去执行if判断

实际上set命令不仅可以显示函数的还可以显示变量。

Unset 后面跟函数名直接删除函数
declare -f 查看本机所有的函数定义。
Declare -F 查看函数的名称。

: . function 这是挂载了这个文件里得所有函数
删除shell函数及centos6上得函数文件

函数有个特点,一个函数只能在当前的循环脚本中有效。开启一个子进程就用不了了,除非变成另外一种函数叫环境函数。怎么让他声明为环境函数那就使用export -f就行了,所以需要把function这个存放函数的文件在声明一下。↓↓这是声明了is_digit这个函数块,这样他就变成了环境函数。
:这是action的函数源,在脚本中加入这个在配合action使用即可提示语句打印功能
:6上面也支持函数。
有个函数 action下图绿色的字就是调用action打印出来的。
action提示语句打印功能
action 后面跟提示语句就可以就是可以提示OK
如果想失败:↓↓后面带个false就是提示失败。

注意在脚本里尽量用PATH变量写全路径以免脚本找不到执行命令的路径↓↓

函数的局部变量

环境变量让我们子进程也可以使用,而普通变量子进程就不能使用了。在函数体里定义得变量将影响函数外得变量值,函数定义得变量得工作范围是整个shell得当前终端对话,这是我们不期望得,要想把函数体得变量加以限定,把他约束在函数体内部有效得使用方法就得使用:
local(英译本地)关键字把他声明在函数体内部有效,只能在函数体内部使用,在函数体外面得变量将不受影响。例图↓↓
:该图意思是local得工作逻辑及使用方法。一开始我创建了一个函数体,在函数体使用之前我便输入了local声明了此函数体得变量为函数内部使用而NAME变量为马哥然后退出函数体,在外面我在给NAME赋值变量为wang所以使用函数体得时候变量才等于mage,而不使用函数体在外面使用NAME时变量为wang。
所以正在函数体内部使用得变量必须得加上local避免脚本里和调用得函数体得变量同名了产生冲突。

函数有自己得变量,还可以嵌套使用。那就涉及到一个复杂得逻辑叫递归递归调用 !!
函数环境变量。

函数里还能使用嵌套
局部变量:
函数体里的变量将影响函数体外的变量。
Local 可以限制函数的变量。在函数内定义的变量只有函数体内有效,除了函数外,变量无效。

  函数递归

所谓递归就是调用函数自身,自己调用自己这就叫递归。
在有些场景下会用到递归行为,
函数递归得层数极限取决于内存的大小。
:bash -x 跟踪命令执行信息。
递归层数的极限取决于内存的大。嵌套是有可能造成系统崩溃的。

:():|:&;:
这其实就是一个函数 : ()为函数名的格式 函数分阶符 : 还是一个字符利用|管道创建子shell:也是创建子shell &表示后台运行,该命令是创建子shell调用创建子shell一直创建,直达系统内存耗尽崩溃才停止最后一个:是执行函数
:ldd命令可以查库。

信号捕捉trap及用法

信号捕捉说的就是当我们 希望一个进程受到某些信号以后不按照信号的原有行为操作。
trap命令可以是个内部命令可以捕捉任何命令。
trap的选项有两个
-l
-p 是列出信号定义得行为
基本语法:
trap 跟上参数在跟上信号。信号可以跟好几个,参数可以让捕捉到这个信号之后执行的命令。当一旦某个命令发生了我们就可以触发一个信号的执行。
基本得写法:
trap后面跟信号,这个信号一旦发生就可以让他触发想执行的命令。
如何在脚本中屏蔽掉CTRL +c 。↓↓
:trap信号要写在当前脚本的最顶上得先定义,如果不在前面定义,他就会不捕捉,按下ctrl+c 就停下来了。该命令得意思是:
1.Trap 先定义捕捉的是 int信号(killall -2选项CTRL+C)就提示按下了ctrl+c键
脚本执行结果:且不能终止该脚本得执行。
:trap -p 可以进行打印功能。能够看到我定义得信号是啥。
2.trap ‘ ‘中间啥也不加是忽略信号。
:该命令意思是从0到9就是捕捉这个信号且不能按CTRL-c强行退出,但是到了下面个循环就是什么信号都不捕捉啥都不干,10到20之间就可以按下CTRL+c由于没有捕捉到信号就不再搭理信号了trap 啥都不跟忽略信号。

  1. trap ‘-’ 跟 -是恢复原有信号的操作
    :该脚本意思是到了20至30这段数字之间就可以按下ctrl+c 退出
    trap finish EXIT逻辑:
    这个捕捉的逻辑是自动的捕捉当你无论是什么情况下退出我们都可以让你触发一个叫finish的函数里定义的操作不管正常退出还是异常退出都可以执行finish下的函数。
    :这是先引用了function函数文件里finish这个函数变量,在使用了trap finish EXIT在非正常情况下退出都要显示zhang
    Killall 杀都能执行但是用killall -9 强制杀掉是捕获了的。9信号不能被抓捕。
    数组介绍及用法

所谓的数组就是数据的组合数据的集合。数组:有助于统一管理数据。
数组的下标(或者索引):
所谓自定义格式我们可以不用数组可以用字母,想用啥都行,或者一个单词或者一个英文句子都可以,数组的下标可以用其他自定义格式,而这种自定义格式的数组下标称呼为关联数组,或者关联索引,也就意味着描述某一个数组元素不一定是数字可能是其他的字符串组合。
普通数组下标:(0..9)数字就为普通数组
关联数组下标:自定义格式就为关联数组:一个单词或者一个英文句子的自定义格式
数组在使用过程中有可能出现一种格式(稀疏格式):
稀疏格式呢就是造成索引不连贯。
数组的使用和变量的使用很相似:
在shell中数组是可以不声明的直接赋值就可以,
当然有个特殊场景关联数组他必须先声明在使用
具体语句就是:
declare -a 后面就是带普通数组(不用声明)
declare -A 后面带关联数组(必须先声明之后才能使用)
而且二者这件一旦定义完无法在相互转换。不能把关联数组转换为普通数组,或者把普通数组转换为关联数组。
关联数组:需要先声明在使用不然会出错,优势是利用关联数组下标这个特点可以使用键值对。
: - a选项列出所有的数组。
:- A选项列出所有的关联数组。
数组赋值及取法

变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量的集合
数组名和索引
索引:编号从0开始,属于数值索引
注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash4.0版本之后开始支持
bash的数组支持稀疏格式(索引不连续)
声明数组:
declare -a ARRAY_NAME
declare -A ARRAY_NAME 关联数组
注意:两者不可相互转换
关联数组的定义需要我们用 declare -a(A)来声明之后把里面每个元素进行赋值,赋值之后相当于每个数组就有东西了。数组的赋值可以用很多种方法来赋值。
关联数组需要先对数组名进行声明,才能进行赋值否则就是错误的,最好就是都声明。

数组的赋值:
(1)一次对一个元素进行赋值:

(2)一次对全部元素进行赋值:
:这是对ceo coo cto赋值,两边用()分割中间用空格隔开,
(3)一次性只针对某一个特定的元素赋值

(4)交互式的赋值。
:使用read -a 对这个数组交互式的赋值。FUZHI等于zhang li wang。
数组元素的引用及各种取法

数组元素的个数减一就是我们最大的数组元素的下标。想增加一个新的下标就是拿数组元素的个数作为新的数组下标即可。
1 取其中的一个元素:
花括号括起来中间加数组的下标外面还有一个$符号。

2 取所有的数组元素:
需要在最后加下标处*号或&符号。

3 数组的元素个数:
在数组前面加#号
:这个数组里有3个元素。

在数组中是从0开始算起。所以3就相当于4,只要能生成数字序列或元素序列的语句都可以放在:↓↓

甚至还可以使用通配符:↓↓

还可以使用命令取数组:↓↓

新增元素赋值:↓↓

Unset可以删除某一个数组元素:↓↓

删了之后只是空了一个下标编号的赋值元素,所以在创建的时候所有赋值元素也是一样的。这就是稀疏格式。
:这是删除了整个数组名,所以查看也查看不了这个数组的信息
关联数组需要先声明后使用:
这就是关联数组。一个数组里可以存放很多个变量值。

数组可以从中取出他的某个元素值,也可以从中取出部分元素值。
数组切片就表示:
从整个数组元素中挑取出从什么位置开始到什么位置结束之间的所有元素而不是一个一个取。
语法:
$ARRAY[@]:offset:number :表示的是从数组的第一个开始跳过多少个取多少个。

字符串切片类似于sed命令

在shell中也可以对字符串切片:
:而且必须加空格。

在centos6上不支持/
:空格注意

在centoc6不支持。

字符串根据模式来取串。
:但它不是贪婪模式,找到第一个就停了。:这是贪婪模式##*后面加指定要删除的字符

在左边就是从左往右找,在右边就是从右往左找。
:从右往左找的贪婪模式。

:$LINE/root/admin
:类似于全局替换
#表示行首:↓↓

%表示行尾:

删除:↓↓

贪婪删除:↓↓

转换大写:↓↓

转换小写用逗号逗号转换小写:↓↓

高级变量赋值语法

在有些场景下我们希望根据某一个字符串的值来决定对另外一个变量的具体赋值。
传统的方法就要判断了if,判断这个str到底是啥状态。然后来决定我的赋值。但是在shell中有一种高级的变量赋值语法用一条命令就搞定了。
语法不一样得到的结果不一样。
(第一个语法):当str的值没有配置,根本没有这个变量的时候var的值就是后面这个表达式的值,如果str为空字符串,var就是一个空的字符串,如果str是一个非空的字符串那var的值就是str的值。
现在这个var的值多少就有str 的状态来决定。
变量赋值的三种状态:
1,没有这个配置

2,这个变量为空

3,这个变量为一个非空的字符串

变量的高级用法

在shell中我们定义的变量通常不不需要去声名他的类型的。直接就可以对变量赋值可以使用了。但是在shell中也提供了两个关键字它可以用来声明变量的类型,一个叫declare一个叫typeset但是在生产中一般都很少用typeset这个命令他已经被declare这个命令替换了。

该变量还可以组合选项来使用。
declare:
-a 显示所有数组。
+/-  ”-“可用来指定变量的属性,”+”则是取消变量所设的属性。
-f  仅显示函数。
r  将变量设置为只读。
x  指定的变量会成为环境变量,可供shell以外的程序来使用。
i  [设置值]可以是数值,字符串或运算式。
eval命令及用法

在有些场景下使用还是非常重要的,eval是一个内部命令,将后面跟的参数作为一个shell命令来执行。
两次扫描:
第一次:先把后面跟的这个参数替换成最终的结果,如果是变量的话就用变量的值把他替换了。
第二次:执行替换完了的结果,最终是要把后面这个参数作为命令来执行。

:变量里可以存放命令的,这就是动态命令。
动态命令:可以随时根据变量的改变来修改命令(用变量来存命令)
静态命令:写死的命令

:而这的\$$是转义的意思等于TITLE的两次变量

mktemp该命令是专门用来生产零时文件的一个命令,而且的生产的文件路径是可以随机生成的,随机生成的字符有几个有用户加X决定,有几个X就有几个随机字符,至少3位。

-d 创建临时目录
-p 指定目录创建零时文件

:mktemp 后面跟路径在这个路径目录里就会随机显示创建的零时文件。
:这是在当前时间创建随机文件。

:-p 指定目录创建零时文件

相等于cp复制,同时不仅具有cp复制的功能,而且还有设置属性设置权限的共功能就相当于多个命令的组合
Install=cp ; chown ;chgrp ; chmod ;mkdir。

:这是将/etc/passwd 这个文件拷贝到/data/passwd.bak2 这个文件中,修改了-o(所有者)为wang,所属组-g为bin所拥有,-m 是700权限(读写执行权限)。
expect介绍及用法
可以用来实现交互式操作变成非交互。
逻辑:可以捕获你执行命令的过程,发现有特定的关键字就自动捕获。

expect脚本不能用bash来执行只有加chmod +x 执行权限才能执行也可以加expect
Expect基本的语法可以用交互式方式来使用。正在使用都是嵌入到脚本中去使用,在expect里面可以嵌入很多子命令。其中这些子命令包括:
Spawn :
让expect来监控某个命令,替代人工执行交互的某个命令,所以spawn后面跟的就是要交互执行的命令,一旦用spawn激活以后expect就开始监控,如果出现了关键字,就可以事先约定好的字符串用send命令发给spawn,之前交互式的命令用send命令来接收那些字符串,send命令后面跟的东西就是以前手工要输的字符串
Send : 用于向进程发送字符串,匹配到指定出现的字符串时就执行命令
Expect :
监控前面启动的进程,是不是出现了特定的关键字,如果出现特定的关键字就用send向他发东西,
Interact : 允许和用户进行交互。
exp_continue: 匹配多个字符串。
expect语法及写法

:使用expect 后面加expect脚本类型就能执行该脚本。
:创建一个expect脚本后缀
单分支语法:
中间包括输如的字符串都显示
多分支语法:

expect 脚本写法:

:由于不是bash脚本所以的给他加执行权限chmod + x↑↑

:Interact:允许和用户交互。

:可以支持变量。↑↑

:支持位置参数↑↑

执行多个命令↑↑

Shell脚本调用expect。↑↑
:↑↑分别对应的是上面脚本的位置参数
使用expect编程多个用户方法↓↓
实现让expect脚本创建多个用户的首先创建一个存放ip的文件。而且还要知道密码。

以上是关于shell脚本编程高级篇的主要内容,如果未能解决你的问题,请参考以下文章

Shell脚本高级编程实战第二部

shell脚本编程之基础篇

Shell脚本编程——基础篇

六Shell脚本高级编程实战第六部

七Shell脚本高级编程实战第七部

九Shell脚本高级编程实战第九部