00:00
好,呃,那么在函数内部,呃,也是可以使用自己的专有变量的啊,那么虽然说我们本身share中就可以使用变量,但是函数里面使用变量和我们share中的变量有时候并不一样,比方说我这定一个函数啊,这个函数呢,呃,起个名字。啊,我定一个测试用的函数啊,那么在这呢,我去定一个变量名叫内蒙王马哥吧,好,然后呢,我把这个函数呢,这个变量打印一下。
01:00
然后画括号。然后现在我去执行一下这个函数。啊,大家看它能把这个变量打出来,那现在车很可能会产生这样的一个问题啊,什么问题呢,就是我在当前的这个环境中也有一个内蒙,但是我的值呢是王。那现在请问大家,当我去定执行这个函数的时候,打出来的到底是王还是马克?啊,我这定义了一个name是王,打了一遍,现在是王,那现在我执行完函数以后,这个函数不知道打印name吗?那打印的到底是谁呀?马哥,那现在我再执行一下内,那打印出来谁是不是出乎意料啊,啥意思啊,就是说函数执行过程中是不是把我的系统的变量给改了,对不对,你觉得函数里面用的变量。
02:26
去把我函数外的程序的变量改了合适吗?是不合适,所以为了解决这个问题,我们这么来干,我把这个变量函数给它删了,这个可以删函数啊,用onet就是跟跟删变量一样啊,可以删掉,删掉重新定义,那么怎么定义呢?这么定义大家看啊,我们为了确保我们定义的函数里面用到的变量只是在函数体内部有效,而不要影响函数体外部的程序,那么方法就是在这个地方加一个关键字就好了,叫logo。
03:01
Local就是这个name,这个变量只在函数体内部有效,不影响函数体外部的程序。啊,这样的话,你看我这儿也是有个内蒙,假如说我第一个,呃,换一个吧张,然后我现在去打印一下name章,然后我把这个函数执行一下fun test,看那现在我再去执行一下name,你看不影响了吧。啊,你看name的值还是张,不至于把我原来的变量给破坏了。所以我们函数体内部如果要用变量,建议大家加上logo,如果你不加logo,它就会影响你函数外部的程序的变量,我们说函数是一个模块,用完了就乱算了,结果呢,你还影响别人了。
04:00
万一多个函数共用一个,都用到这个变量,那互相就会产生干扰了,明白吧,所以加local关键字是一个比较好的。选择,那所以呢,现在你看这个函数啊,我们这么做完以后啊,我这曾经写了一些脚本,大家再来看,你就明白我当时写脚本这些是不是用到了这个函数的思想。啊,你看我打开一些之前写过的脚本。好啊,你像这有一键安装买CQ的啊,这个可以看一下这个脚本。
05:02
还有更为复杂的,比方说一键搭建word press博客的。这个脚本呢,稍微复杂了一点,所以呢,我就用到了一些变量,就用到了一些函数的写法,用到了一些函数,你看这里面,诶,这是什么意思,是不是用到了系统一带的这个函数。然后这是一些变量,这是一些变量,这就是函数,看到没有check。这个check是检查相关文件是不是缺失的,如果缺失了文件就没法装了,这个是装买C口。啊。然后最终实现了两个函数,一调用就完了。啊,下面这个word press就更为复杂一点,然后前面是变量的赋值。然后接着你看这是检查文件一个函数,安装MYSQL一个函数啊,还有就是安装NGX一个函数。
06:00
还有HTTP,这是配置文件,这不是函数。然后还有。安装word press的一个函数啊,你看这还落落了一个到的PPPP应该也在前面。啊,这有PP的,所以每个都是同函数实现的,所以最终把函数写完了以后一一执行,是不是挨个写一遍就完了。这样的话,这个语句块条理非常清晰,将来万一说我想改改MYSQL的安装,比方说想换个版本之类的,那你就改MYSQL就行了,不影响别人。对吧,这就是语句块编程思想啊,当然具体哪个模块干了什么,你们当你们学到后面的时候,自然就看懂了啊,现在可能还不知道MYSQL啊,这些东西干嘛的啊,具体怎么配还不理解,那等你们学到后面的时候,你看这里面这些东西至少能看懂,大家看这是不是if是吗?这什么意思,这是不是就是这个Dollar n g X这个,这是个文件,你看它是个变量,就代表一个文件,这个文件是否存在,当然叹号的取反就是不存在是不是,如果这个文件不存在,是不是就直接报,提示说这个文件缺失,缺失就直接退出了,看到没?那如果对应的MYSQL文件不存在,直接缺失,对应的PP文件不存在,就缺失直接报,所以最后呢,就如果都没有问题,那就成功了。
07:29
对吧,就准备好了,然后后面就是一个一个去安装啊,具体的安装,所以这里面实际上。也很简单,都是一些Linux命令啊,甚至这里面好像都没用到,循环都循环都没用上啊。非常简单。好,这是给大家介绍的这个函数的使用啊,当然函数还有一个非常有一个特殊的地方,就是函数可以实现相互调用的同时还可以实现。
08:11
自己钓自己。大家记得我刚才曾经写了一个函数,这个函数里面这个想一想这个函数里面是不是调用了另外一个函数。是吧,就是我这个OS version是不是调用了上面这个函数。这是函数的调别的函数,这是可以的啊。那事实上在咱们的系统中就有这样的函数文件,这个文件里面就大量的函数,它都是彼此调用的啊,比方说我们这有个action。这个action呢,本身是个函数。这个action函数它被别人调用,你看被这个函数调用。啊,被别的函数,你看这个action就是个函数,它被别的人调用,当然他又调用了success success本身也是个函数,你看这个success函数怎么定义的。
09:11
塞函数它怎么定义的?那这是e success。你看这不有吗。那这不有个success函数。所以函数之间互相调用是完全可以的,当然除此之外,甚至函数还可以自己调用自己,自己调用自己,这个就叫递归,递归,递归调用函数自己调用自己,那什么场景下会用到自己调用自己的场景呢?比方说。咱们实际上这种思想大家应该见过,比方说我们最早见过的基因优。
10:02
Guu什么意思?是不是自己调用自己g is not unix,你想他是不是确自己掉自己了?啊,这就是,当然我们之前学过RPM,是不是也这样?RPM什么意思?RPM就是RP包管理包,Manager management。包管理或者叫manager是吧。所以他这都是自己调用自己的例子。那么在我们学函数的时候,函数互相就是调用,可以理解,那么函数自己调自己,什么时候会有呢?哎,比方说。这个函数。
11:06
啊,我去。找一下函数的低估,调用这个。大家看这边儿有一个数学上的术语叫阶乘,那这个阶层是这么来说的。啊,这个是1808年200年前发明的一个数学运算的竖式公那个术语啊,那么他说的是一个正整数的阶乘是所有小于等于该数的正整数之积。并且零和一的阶乘是一自然数N的阶乘,我们一般写作N叹号。那N的阶乘,那按照刚才的定义就是从一乘二乘三一直乘到N。这就是他的阶乘,那事实上,那么如果是N减一的阶乘怎么算?N减一的阶乘是不是就是?
12:00
如果是N减一的阶乘怎么写啊?N减一的阶乘。N减一的这些乘,它等于什么,是不是就乘一乘一乘二乘三,哎,乘三啊,最终乘到那个N减一。最长乘到N减一是吧?哎,那它和N的阶乘之间有关系吗?有有关系,啥关系呢?实际上它不就是N减一的阶乘乘N吗?是不是这个道理啊啊,N减一的阶乘乘N嘛,啊,这不就是它的关系吗?那么N减一的阶乘,它也是阶乘啊。N的阶乘不也是阶乘,所以如果我们用函数来表示阶乘的话,那是不是它就是自己标自己了啊?
13:06
对吧,这就是递归调用。自己调用自己。那比方说我们就用这种思想来实现。比方说我现在要想实现十的阶乘的计算。那怎么算?十的阶乘是九的阶乘,乘十是不是这意思?对吧,那我要是,那我要算出十的阶乘,我就得算作九的阶乘乘十,那九的阶乘多少啊哎,那九的阶乘我们再求嘛,九的阶乘是八啊,乘以八的阶乘乘以十嘛啊乘以九嘛,是不是。那那我算八的阶层,那八的阶段就是七的阶乘乘以八嘛。是吧,啊,当然那那我七的阶乘也不知道,那再往下看吧,所以那一直到最后是不是就是一的阶乘啊,当然二的阶乘,那我我还得算成一的阶乘,乘以二,那一的阶层我得知道结果,不过一的阶层有定义啊,啥定义啊,人家说了说零的阶乘和一的阶乘它们都是一啊,都是一。
14:15
都是一。所以呢,这不就有结果了吗?我从。往上走,终于找到了你这边是一的阶层,是一,那就把它替换成一,那么把它替换成一以后,那么二的阶层不就知道了吗?二的阶层知道了是不是三的阶层就知道了,三的阶成知道了,一直往上走,是不是最终就算出十的阶层了?所以呢,这个逻辑呢,有点像什么呢?下台阶上台阶,大家想想我们刚才通过这样的一个逻辑,我要算十的阶层,我得先先求出九的阶层来,那九的阶层我要算,我得先算八的阶层,一直到最下面一的阶层,是吧,A的阶层是有结果的,我通过一的阶层是不是就退出二的阶层来了,二的阶层推出来三的阶层,最终是不是把十的阶层就算出来了,你想他这个是不是有点下楼梯上楼梯这个感觉。
15:03
对吧,当然总得有底,要没底儿,那那你一直下去,一直下去。那总那没底,没底不就回不来了。没底回不来了,那最终就系统崩溃了,为什么?因为他要记住你原来的阶层,你你你现在你从十的阶层进到九的阶层,是不是原来十的阶层还得还在,内存是存着的,因为待会还得回来嘛,所以呢,你这个时候呢,你一直往下走,你总得有触底反弹的时候,没有底,那那一直下去,内存终究会消耗殆尽的。就崩了。啊。所以呢,这个一定是有一个兜底的时候的啊,当然你这个层也不可能太多。你要层来个1万次,难道1亿次他也能兜得住,有底儿,但是底也不能太深吧,18层地狱也就18层了吗?你不能再再多了吧,啊,总得有个层次限制吧,那多少层呢?哎呀,这个东西你想测的话也能测,呃,怎么测呀。
16:10
啊,一直往下下,那你就定一个定一个这个测试啊,定一个测试,呃,那我们就定一个测试,我们就测一下有多深,那这个怎么测呢。那我们就测这样吧。呃。我就自己调自己,自己调自己,但是这个自己是干嘛呢?就是减一啊,或者加一吧,加一加一啊,那这时候我们有一个变量的值,让它不断的加一,比方说我们A等于一,先给它初始值。然后通过T的函数,我们去让它加一,I加加。
17:08
然后加完了以后调太子的函数。亚太函数。啊,但是这个分号不用加啊,那大家想我加完一以后,就我把这个打印一下吧,打印一下I等于。都来,然后再调自己。再挑函数自己,那它调用函数自己的时候,他是不是又开始讲啊,又开始去打印,那这是不是就是自己调用自己的典型的死循环,但是由于我没有定义任何退出条件,所以它是不是一直会加上去。但是难道能永远的加下去吗?我们说嵌套深度你也得有限制啊,对不对,你不可能一直无穷无尽的加吧?啊,那我们来试试吧,看看他能嵌到多少层呢?那我们就看这个数不就多少了吗?他最终最终前面能打,后面应该就打不出来了,哪个最后打不出来的那个数字,最后打出数字不就是多少钱吗,是不是?
18:17
那我们就看吧,它嵌套多少层,这18层地狱有多深,看看测一下就知道了。啊,行了,崩了。8589层,这么多层终于顶不住了,看懂了吗?哎,这就是他的极限,当然有可能和系统有关啊,因为我这个系统分配的内存也不大,我才一个G,如果是你们的话,你们内存分大一点也许。这个层会更多啊,你们可以测一下,看你们那儿多少层啊,我刚才咋写的呀。
19:08
我我刚才有有大内存的同学可以测一下啊。啊,我这把这个案例写这吧。我写的是我这前面let I加加,然后是打EI。然后调用那就这么简单嘛,这这个函数,然后定义完以后就执行一下它就行了,是吧?啊呃,没事,你不写它就是零啊,你默认I不负值就是从零开始,你们撤了吗。
20:32
看看你们那个是八层地狱,和我这儿一样吗?我这是8500多层。这可以测试啊,这个层递归的的嵌套深度。也是一样的是吧,都这么多呀,8586是不是内存可以调大点。
21:08
内存调大点,我因为我的内存比较小一个G嘛。啊,郝总你这个都7727啊,这个版本不一样,可能是或者资源使用不一样。但每个人都不太一样,8590,哎,你和这个孟玄聪你们俩一样,我是8589,基本上也就到这个阶段,8581反正差不了太多。这8000多层,所以呢,我们在定义这个递归调用的时候,一定要注意它的深度不可能是无穷无尽的,一定是有要求的,8589,你们内存都这么都这么大吗?都是一个G吗?有没有内存大的都一个G,那就跟我一样了,那就不要了,我们就调内存大的,把内存调大点的。
22:21
所以这个递归呢,尤其在一些复杂的场景下,递归还是很有用的,因为如果你要不用递归,咱们并不好算出它的值来。你像刚才说的那个阶层,那个阶层实际上不用递归也能实现啊,不用递归也能实现啊,大不了变个循环,N的阶乘不就是从一乘二乘三乘到N不就完了吗?那我们用阶层的实现递归,那递归的话呢,我们看一下这段代码啊,我这有那个递归它的一个脚本,好,我们写一个递归的脚本。
23:23
好,大家看这段脚本,它是啥意思?首先fun是一个函数,后面跟个DO1 do1呢就传一个参数给他,比方说传十,那就十的参十的递归,呃,十的这个阶乘,传八就是八的阶乘,就这个意思,然后这个算是它的名称。然后先判断得一,它是不是零或者是一,如果是一零,那就直接返回值就一不就行了,如果不是一,那我就求这个函数啊,当前你是第几个什么的阶乘,比方说你是N的阶乘,那就是N减一的阶乘,乘N就行了,所以呢,我们这看是到一,到一就代表这个N。
24:10
乘以谁呢?乘以这个函数是什么函数呢?是到了一减一,那就是N减一的阶乘啊,当然这个值呢,比方说我们刚开始如果是放个十,它进来以后一看,十是不等于零不等于一的,所以它就会把这变成十,然后这个去求放个十减一就是九的阶乘,那九的阶乘它又得去调这个函数,那九阶乘是啥呢?九的阶乘是九乘八的阶层是吧?然后不断的去循环循环循环进去。最终诶,终于有一次减成一了,那就有结果了啊,有结果了它就会不断的返回,所以呢,阶成调用它一定是有一个结束的条件的,这就是这个兜底的啊。
25:04
最底层了。好,那现在我们把这个函数写完了,写完以后呢,我们来写一下,比如说十的阶乘,这就是它的值啊,你看三的阶乘,这是它的阶值,但是千万别写错了,如果我这忘了写数字了,大家想想会导致什么结果?你没有写相当于DOLLAR1是空,空的话呢,你判断DOLLAR1是空吗?是零和一吗?不是,不是的话它就会减一,那么减一的话呢,那就是空空就相当于不成了吗?那么是不是就减一成了负一的阶乘,负一的阶乘,那它没结果呀,是不是它就会换去算负二的阶乘?
26:01
因为减一嘛,负二的阶层也没结果,他就会算负三的阶层好,那你就最后崩了,因为它没有底啊,一直会减下去的,所以你看。啊,当然它这个地方,因为我们这儿用了一个中文号,中文号这是不是判断它这个条件是相当于少了东西了,少了东西以后,它这结果就相当于负一,负一这个语法是不对的,所以就卡在这了,啊负一就是空嘛,负一。好,看看这出了什么问题的。哎,你看我这机器已经卡死了,为什么呢?因为他一直在阶层往下走走走走,结果呢,造成你看已经剪到这儿了,好像看见没。啊,已经出现了内存不足的现象了,我这已经内存完蛋了,已经完蛋了,看看内存怎么样了,你看用了800多兆内存了。
27:16
是不是马上你看swap分区都用了1.6g了,是不是就崩了,内存用光了吗?啊内存用光了,这CTRLC可能都不好使了,你看我敲命令已经完蛋了。这实际上就是一种黑客攻击手段,是不是就把你的系统搞瘫了嘛啊,我就重启一下了啊。那这就是这种攻击啊,那当然这种攻击,实际上你要是搞破坏,咱们这有一个更加厉害的攻击方式,这攻击方式是著名的一种叫fog炸弹。
28:03
这个爆炸弹呢,是一个恶意程序啊。他的逻辑就是利用递归调用,不断的去大量的瞬间产生。紫禁城,而且呢,由于它用到了。管道,所以它就可以瞬间以指数性的增长大量生成紫禁城。最终消耗你的资源殆尽,导致系统崩溃。那么这个实现的爆炸弹,它是用。各种语言都可以实现的,比方说用C语言,用Java,用Python,用share都可以,那我这里面呢,用的是线的函数实现的,大家能看懂这段指令吗?这段指令实际上就是一个爆炸弹。看起来好像不容易看懂,实际上啊,就是故弄玄虚,它用冒号实际上就表示函数名。
29:09
啊,你完全可以把这个冒号替换成一个你比较熟悉的函数名,比方说Bo,这是不是就看懂了。啊,然后这个不就是换成函数名,这就是函数名,这也是函数名。你这不就看明白了吗?这啥意思啊,就是这个函数里面调用了自己,同时有管道传给他,我们都知道管道会开启紫禁城,所以他就报幕,就瞬间指数性的增长了很多紫禁城。而且呢,这个地方加了个符号是后台执行。所以这样的话就可以并发的同时大量生生成大量的BOM子进程,这时候定义完了以后再执行一下boom,这不函数就执行了吗?相当于前面是定义,后面是执行嘛。这样的话,你的内存立即消耗殆尽,大家看,现在我正常我的内存才只用了100兆。总共有。
30:09
一个G的内存现在只用了100兆,Swa是不是也没使用,说明了内存是。很够用的,现在我立即执行一下,你会发现马上就崩了,走你看看这边儿。马上,这命令都卡在这了,因为内存给你用光了。啊,实际上你的系统就崩溃了,内存用光了呀,你看我这自己查看内存多大就开不了了,直接就给你搞崩了。当然他只他没有给你删文件,所以大了机器重启是不是就好了。对吧,这就是一个很著名的爆炸弹。这个爆炸弹呢,在互联网上有好多那个其他语法写的,比方说你用share写,也可以用脚本写,脚本写就是自己掉自己嘛。
31:06
啊,这个地方写了个DOLLAR0,到零还记得什么意思吗?到零就代表着函数自身的名字吗?是不是这个也可以啊,最终呢,你会发现内存不足,它会出现OM提示啊,当然我这还看不到。OM呢,就是内存不够了,诶你看看见没,是不是这个内存已经用了800兆,Swap都用了400兆了。如果SW也用满了,那是不是就彻底就没了,彻底就崩了?所以他,诶,你看我就终于看见了,看,这就是内存崩了,Out of memory,这是以后你们将来会看到的现象,有可能啊,就是说白了就是内存用光了,Out of,就是超出了内存可使用的量,那怎么办啊,被Q掉了,他把谁给杀了?
32:01
他杀了751进程,插了诸多的进程,这些进程。这些进程都被杀了啊,你一个的进程全被杀了,唯独就没有杀刚才我们死循环那个进程是吧,所以那这样的话,你的机上有好多进程莫名其妙的就被Linux给杀掉了,哎,说不定的机上正好跑了一个非常重要的数据库服务,刚数据库服务被杀了。那你的系统就完蛋了啊,你看这个现象我这了。他。哎,这就是递归调用,递归调用,那么递归调用呢,在。这个地方有一个非常经典的递归调用,就是这些,有一个叫汉诺塔的,这个汉诺塔是一个古代的小传说啊。
33:14
传说是这个印度的传说。说有一个叫大梵天创造世界啊,这个印度是大梵天创造的世界,中国谁创造的世界,盘古开天地是吧?啊,这个大翻天就类似于盘古啊。然后他呢,做了三根金刚柱啊,这三根金刚柱啊,金刚柱呢,每个柱子上面落了第一个柱子落了64个盘子,最大的盘子在下面,最小的盘子在上面,大梵天要求有一个叫婆罗门的。把圆盘要从第一个柱子给它,最终挪到第三个柱子上,在挪到的时候有规定说每次只能移一个柱,移一个盘子,而且每次移动必须小盘子在上,大盘子在下。
34:06
现在要求你怎么去把这些盘子最终挪到第三个柱子上去,你可以借助第二个柱子挪。啊,最终挪到这边来。那这个挪动呢啊,是数学上比较经典的使用递归。函数调用的一个典型代表。啊,你看这个东西我要挪,大体上N个盘子要挪到这边来。它是怎么实现的?你要把N个盘子挪到这边来,前提是什么?前提是把N减一的盘子先挪到这儿来。是吧,然后把最下面这个大盘呢,挪到这儿来。是不是然后再把N减一的盘子从这个柱子借助于它这个柱子挪到这边来。是不是是不是可以分解成这个动作。
35:04
啊,这就是地位调用的电信代表。你要不用递归调用这个东西,你还真没法算。就很难用传统的算法来实现,所以这就是个典型的低归调用。那这个低估调用呢,要写成脚本,怎么实现呀?啊,我这儿已经有脚本了啊,大家可以看一下我这个脚本的实现啊,啊这个脚本,哎,待会我就把那个发的机器重启一下,把这崩了已经。好,那我这个脚本呢,事先写过一个叫汉诺的汉诺,这还有一个汉诺,三个汉诺文件,先用这两个算法,一有一个是用函数,这个应该是用函数写的。
36:11
你看这是函数,这是调用了一个汉诺的函数。然后这个实现的代码很简单,就这几行,不过呢,你要是逻辑上比较差的话,这个问题你就可以不用看了啊。比较绕,虽然代码很短,就那几行,但是有些同学绕不过弯来,我觉得你为了为了避免打击你的积极性的话,你就不要看了啊。这个有点绕。如果同学基础好,数学好,可以看一看这段代码。好,那我看一下,你看我这个脚本怎么实现的啊。
37:05
好,我把这脚本都给扔过来了,好,那跑一下汉诺。哎,输入盘子的个数,我也不输64个了,因为64个太多了,我就输入三个吧,这就是三个盘子的挪动方法。第一步,先把第一个盘子,也就是最上面那个小盘子从A柱子挪到C柱子。第二步,把第二个盘子从A柱子挪到B柱子。第三步,再把第一个盘子从C柱子挪到B柱子,后面我就不讲了,大家知道这意思了,最终就实现了盘子的实现挪动。当然为什么我这三个。啊,来个64个,那个刚才故事里边不是要求64个吗?啊,你别弄了,因为这个时间太长了,我们就十个,你算算就知道了,假如说我们就十个啊,你看它十个用了多少次挪动1023,实际上大家应该能猜到你的盘子个数和挪动次数之间的关系,那关系就是二的盘子的个数是方。
38:29
你看十个,那就二的十次方减一,那么你要挪动,你要64个盘子,它这就是它的挪动次数,你看这个次数多少,你这辈子也挪不完,下辈子也挪不地球到地球,地球都可能灭,灭亡了,地球到这个宇宙诞生到现在才100,一百一百不到40年,呃,140亿年。140亿年就是地球啊,就是这个宇宙诞生啊,你看130多亿年,就算140亿年,你看这多少年,这是个十百千万是吧。
39:09
十万百万千万亿,甚至到这就亿了,哎呀,行了,后面也别看了,还人家140亿,你看人家都你这宇宙毁灭好几轮,你都弄不完是不是。所以这个大梵天给婆罗门布置了一个终身完成不了的任务,是吧,那?当然这段脚本还有写的更好的啊,啊,你看一下咱们这是以前咱们那个是31期的,好像是。31期的同学写了一个更加直观的脚本,那就这个叫汉诺。Po。
40:00
输入一个正数。这是正常正数,比方说啊,十个吧,十个十个,十个太多了,那么就三个吧。六个吧。然后移动次数我们稍微快一点。稍微快一点。看见没?这是咱们以前学生写的啊,是不是看的很直观呀?这是真正的汉诺塔是吧?你看他咋移的,一层一层咋移的。那你别说写了,你就把人家的脚本理解理解就行是吧,理解了就需要花比较长的时间,当然他这个脚本不是一个人写的。是三个人合作写的。啊,共同研发了一个汉诺塔的啊脚本。啊,这个时间太长了啊。
41:02
哎,这就是这三个人写的。叫。蔡金水。周赵文光刘腾,主要是应该是赵文光写的。啊,赵文墨写的,那三个人写合作写的。那同学们如果不看这个脚本,咱们班里头能不能两个人仨人合作写一个这样的脚本,应该问题不大啊,这个脚本283行。283号搞定了啊,283所以share啊,这个要学好了,虽然说不能实现一些像传统的开发那么强大的功能,但是写一些甚至有一些小游戏还是可以做到的啊,这还有俄罗斯方块呢,俄罗斯方块也是用share写的啊,你看这个是俄罗斯方块啊,你看你看人家俄罗斯方块咋写的啊,给你跑一跑,给你玩一下俄罗斯方块啊,看真的可以玩是吧,你看可以转,还可以加速,这样对不对,往这边贴吧。
42:36
啊啊,技术不行,玩的不行啊,可以削他还可以削呢,直接削了,看到没有可以消啊,真的可以消CTRLC结束是不是真的是,而且还有中文注释啊,中文注释这个600多号,那这个大家将来我觉得你把这个俄罗斯方块研究一下,基本上你写脚本就通关了是吧,通关了啊,当然现在不要求大家,实际上真的将来上了班你们写脚本没那么复杂。
43:36
没这么复杂啊,甚至也没有特别多的逻辑上的数学那些要求,你就把那些想干的活,把命令堆起来,偶尔用个条件判断,循环循环,甚至都不一定用那么多,那就可以应付咱们的运维工作了,好,这就是,那当然我这留了一些作业啊,下来你们可以把这些作业做一下,尤其这个这个脚本大家可以下来自己写一下。脚本功能是什么呢?这个脚本功能就是它可以跟参数,比方说跟start,跟stop,跟大,跟status,跟上这个东西以后,他能做什么,这下面有说明。
44:26
啊,如果是跟start就相当于启动一个服务,Stop就是关闭一个服务,所以大就是启动重启一个服务,第是看这个服务的状态,这个可以写一下,还有第七个也写一下,这这第七个我们会用。第七个,第七个呢,就是你输入一个命令,这个命令呢,它会用这个脚本自动的把这个命令的对应的程序文件找到,找到以后复制到这个文件夹里,复制的同时它不仅复制目应本身,还会复制这个命令依赖的数,依赖的库,就那个so文件,把它也会按照同样的路径路径这个放在这个目录的下面。
45:07
啊,比方说有一个BA,它就会放到m NTC root下面的并BA项啊,如果说是这个,那也就是放在这个目录下的USR并下的干事,他依赖的库也会复制到全是这个目录下。啊,这是一个我们后面会用到的一个脚本啊,下来你们可以自己看,把它写一下啊,所以这个就是函数的使用。由于在系统中本身就有自身带的函数,这里面有些函数还是可以考虑用用的,比方说在S6上面,我们用这个命令,它是可以看到一些服务的启动和关闭的状态的,大家看旁边是不是有绿色的,OK。这个OK怎么来的?实际上就是用一个函数实现的,这个函数就是在ETC function这里面,它有一个函数叫action。
46:11
这个action函数。他就可以来打印这种绿色的OK和失败的,红色的失败,比方说我想成功,打印比方说山根,山根成功,那这个就可以打印出山根成功的提示。看见没?当然没删啊,就是个提示而已啊,那你要想删跟失败呢,很简单,加个P它就失败了。所以以后啊,咱们想打印OK,那你就加action,后面跟上,你要想在屏幕上显示的字符串。呃,成功成本不用跟失败的话,加个few force就是失败了,就这么简单。
47:04
就是后面跟这个东西决定了你打一个绿色的OK,还是打印红色的失败啊,实际上这个地方你可以它是省略了一个处啊,你写上处的话也没问题,你不写的话也行。不写默认就成功。啊,所以呢,你看我这个脚本里面就好多引用了这个function的。那这里面没有引,这里面引了啊,大家看这里面就引用了。啊,一个月以后我用不用action啊,我用了你看没这action啊,就是如果说数据库存在安装失败,我就后面直接跟跟false,那是不是就显示红色的失败提示,我觉这个这个功能我就不用自己写了,因为Linux里面自身有这功能,我就不用写了。是吧?
48:00
那比方说我们用这个函数来实现创建账号的功能。啊,这个函数在3S8,三七上,三六上都有,这个文件是通用的,大家看都有,但是乌邦tu上没有啊,这个文件乌邦tu上没有,所以你要用这个文件呢,建议前面做一下判断,看看是乌邦tu还是SSS在用乌邦tu没有这个。那所以比方说我们现在想实现一个创建账号的一个脚本,这个脚本我们想利用刚才说的action啊,我们就可以这么来写。啊,这个我就不要了。那点function,不过这个function呢,用的不是我们自己编的function,是系统的function functions。啊,那比方说我们想创建账号,那创建账号的话呢,我得先判断一下这个账号存在不存在,那如果存在,那么我就。
49:05
创建失败就提示失败啊,那这个东西我们怎么做呢?我们就可以把刚才的这个。ID后面跟上一个DOLLAR1,就是判断这个账号存在不存在啊,如果是存在的,那么它就会成功,这个命令返回的结果就是真啊,当然我们现在把它扔到垃圾箱里不再显示,如果存在,那就认为这个账号我就不创建了,不创建了那我就提示账号存在,直接退出,我就可以在这个地方加一个if。啊,加一个if,然后呢,Action。Action说这个账户已经存在啊,创建失败,那失败呢,我们就写个boss就完了。
50:05
创建失败啊。啊,那这应该少了个L啊,Z少了个Z,那如果是不存在,那就创建成功就行了,创建成功我们先user and把这个创建出来。到一串出来以后,并且。单一句话说,User Dollar is created,那同时我们再给他执行一个。Action。啊,这就直接写action就行了,这就可以了啊,Fi结束好,那么现在你看我跟上一个A。
51:08
有点一。啊,后面跟上那个U1的那个参数叫U1。点儿。Functions。608行命令没发现。Action。到了一。呃,If ID判断德一是否存在,如果存在就打印。
52:00
这里不是传了一个U点一的参数吗?我看我这创建出来没有啊,你看把这个账号创建出来了。他说这个行608行意user,这不是后面跟了一个用户吗?啊,那我加上双引号。把它括起来。引起来action,好,然后呢,我们进到这里面来。然后去执行一下。Test,这回来个U2,哎,可以看,如果再来一次U2。
53:00
是不是就存在了,就失败了,那这个是不是感觉不错呀,好看呀。那绿色的红色的,你这个脚本写起来不就不看起来赏心悦目啊,当然这也不是你写的,你不就掉了别人的函数吗?这不省事啊啊,那这个就是很简单的一个写法,那刚才命令应该可能和我们的环境有关系啊,没有没有错。把这个地方的双引号。啊,这个是要要引起来的,不引的话,它当成了好几部分了啊引起来啊,啊这样的话呢,我们现在就把这个函数给大家介绍完了啊。反应代号不需要反应代号,因这是个命令,这个命令的成功与否决定了是否执行,这个不需要加反应代号啊,反应代号什么时候加呀,反应代号是被别的命令去调用这个命令的时候,哎,你这个反应代号一定是这里面是个命令,并且这个命令被别的命令调用对吧?也就是说这个命令二一定是有别的命令调用的时候,那我这就是个作为独立命令来执行的啊,这它用不着去翻翻号引起来啊。
54:31
啊,这是咱们给大家讲的函数的实现啊,这个脚本和这个脚本,我们后面用这个脚本的大概的功能是这样的,我这把那个把这个脚本写好的啊,写好的你们最好自己写,你看它是怎么他们实现的效果是什么啊,我这把它执行一下这个。还得放桌面上。
55:12
那这样BA copy,你看这时候让你输一个命令,比方说BA,这时候他就把bash以及所依赖的库给你拷到一个文件夹里去了,跑哪去了呢?咱们看一下叫MT six root,你看它考这来了,你看你不是写了个BA吗?他就把这个BA所在的路径和它依赖的库都拷到以这个目录为根下的一级级子目录里啊,所以呢,你如果比方说我再拷一个别的,比方说我再拷个if,看你看他是不是把if camera也拷过来了。这边。是不是他依赖的库,但是他没有没有和BA是更多的依赖库啊,如果说我CP,你看这个CP他有没有考更多的东西,CP是不是依赖的一些库都拷过来了,那这就是他的功能,那这个你们可以考虑考虑怎么写这个脚本。
56:12
用这个。CMD这个脚本来实现,那现在你就可以把我们以前要求大家写的一些事用脚本实现了啊大家记得以前我们要求大家初始化环境,你看。这个初始化环境,你现在是不是就可以通通全用脚本实现了,这个初始化环境里面,你想初始化的东西全各自都用脚本来实现,各自都用函数来实现啊,你看我们将来还要判断六和七,这个六和7678。
57:00
他们的这个命令不一样啊,比方说禁用SE Linux这个写成一个函数。然后禁用防火墙。这是禁用S林子,然后禁用防火墙,当然禁用防火墙呢,六和七的写法不一样,676和七和八的写法不一样,这是我们之前写的这个S,大家都是一样的。这个这个写法都是一样的,这个不管T和什么版都一样。啊,但是禁用防火墙,六版本用这个,七版本八版本用这个。啊,而且这边呢,还得加一个命令叫service IP tables stop,这命令不一样啊,七和八用的是一条命令用的这个。
58:05
啊,安装包的话,这一样安装必要的包,比方说你最小安装,你想装什么包,你可以用函数实现修改网卡,修改网卡的话呢,这个七和八才需要实现,所以你要判断版本吧。是不是七和八才需要执行这个,然后你希望用哪种别名,你可以自己加啊,配亚M仓库,亚M仓库的路径是不是也不一样,你看这个渗四的六渗透七,它的路径可以统一,但是三八的那个路径它不一样,比较特殊,所以这时候呢,你就要通过函数来实现。啊,分别用函数啊,全都是用函数。来实现。这样的话,你这个脚本写完了以后,哎,调某一个功能,你就用函数调用就完了。那今天呢,咱们学习的内容主要是围绕着脚本这一部分啊,啊,可以说今天的重点给大家讲了外循环,外循环里面。
59:10
有一个非常特殊的写法,就是逐行处理的where,就那个where read where read的写法,就这个这个写法做行处理,所以呢,你记住着行处理的时候,就用这个where read,想起来这个关键字for循环的第二种语法,咱们讲完了。然后where循环呢,了解一下,因为我们一般用where循环,For循环,最多continue和break这两个呢要理解。啊,Shift可以实现参数位置的调整。还有select的菜单,最后呢,就是function。那方实验就是我们今天学的函数这个。啊,所以希望大家把这个呢消化一下啊,脚本这部分呢,内容还是比较不容易理解的,尤其写好了,确实还需要大量的时间练习,今天学什么新命令了吗?今天好像没什么,呃,今天学了函数的一些这个这个这个一些指令吧,比方说当to是新的吧。
60:20
但是那不算命令啊,那算是一个关键字。Where也是个关键字,它不是命令,不给我写在这儿吧,Where。是一个关键字。还有一个是。这是关键字,它必须要配合指令的啊,还有一个什么break continue吧,这个是命令。Break和continue。Break。Break continue。
61:07
还有啥?还有select吧,Select做菜单的,当然这些都不是命令啊,但是关键字还有declare declare那个之前写过吧,Declare写过了,Declare今天咱们又学了一个什么呢?FF呢,是显示这个函数的列定义的declare,实际上你也可以加个FF是只显示函数名。知道吧,只显示函数名。哎。呃,还有是onset onet早就写过了吧,Onet就是删除变量,现在我们不仅可以删除变量,还可以删除函数。set没有写吗?这上次没写啊,那就onset。
62:03
拉B是看那个错误登录的日志的,失败登录日志,这个呢,我们应该也要知道的拉B。那笔还学什么新的命令吗?第二世界,中国的第二。Action action那不算命令啊,那是咱们系统里面带的一个函函数,那算是个函数,那不算命令啊,C是CTRCTR呢这个。Ctl是吧,啊,今天实际上还讲了乌邦兔的网卡设置,乌乌邦tu的,它那个网卡配置文件语法用的是页格式,还有一个叫net plan plan的命令吧,那个是乌邦tu里面命令啊,别的命乌帮tu里面才能用的叫plate PLA,然后他呃,PLA生效是吧,这是网卡生效的,还有一个叫FPFPFP。
63:22
FP还有什么n mapp是不是?NMVP是扫描的,这个我们写过了。下试。还有吗?好,还有新的吗?啊,没什么特别多的新的了哈。好了,那如果没有新的,那咱们今天呢,就介绍这么多,今天还是脚本啊,脚本下来大家把课后的一些练习,我这有一些练习,大家可以下来试一试,看一看。
64:04
呃,一些难度大的,你可以暂时不写啊,至少得挑着连练一遍啊,这个脚本需要反复的多练才能学好啊,需要写上5000行以上才能刚刚入门,如果你没有5000行就说学不好,那说明你还没有写那么多啊,慢慢练啊,慢慢练好了,今天的课呢,咱们就上到这吧。
我来说两句