欢迎光临散文网 会员登陆 & 注册

ubuntu下第一个的shell脚本"细胞分裂"

2022-08-25 00:49 作者:扎之克  | 我要投稿

关于终端输入执行的一般逻辑,貌似如此:

(这些逻辑对特殊的例如if之类的不管用)

字符串1 空格 字符串2 空格 字符串3.....

字符串1被识别成指令,后面是传入参数,它们间用空格隔开。

如果是这样 空格xN 字符串1 空格 字符串2 空格 字符串3.....

字符串1依旧是命令,后面是参数。

./cell0.sh是当前目录下的shell脚本或者说是当前目录下的自定义shell指令也行


字符串1 空格 $字符串2 空格 字符串3.....

字符串1是命令,字符串2前面加上$,如果某个变量名(变量名必须是英文)等于"字符串2",那么传入参数1是这个变量的值。


字符串1 空格 $(字符串2) 空格 字符串3.....

传入参数1是指令"字符串2"的输出值。(括号内必须是指令,否则会出错)

字符串1 ; 字符串2

如果两个字符用分号隔开如上,那么字符串1和字符串2都是指令

按如上逻辑来解释下面的命令

音乐/CloudMusic下不存在文件,所以指令ls的输出结果必然是空字符串。

-z是"["指令的参数,用来判断字符串长度是否为0,字符串长度为0,则整个指令输出1,否则为0。

先看看关于if语句的逻辑,貌似是这样

if 指令

then

  指令1

else

  指令0

fi  

关键字if加空格隔开后跟着一个指令,如果这个指令输出1就执行then命令下的指令1,否则就执行else指令下的指令0,fi是if语句结束指令,fi实际上就是if反过来写,case语句的结束指令esac也是case反过来写。

根据大神的文章(详见https://www.cnblogs.com/include/archive/2011/12/09/2307905.html)

"["是一个命令,[...]里面的内容是命令的参数,"]"应该是命令的结束符号(我猜的)

https://www.cnblogs.com/include/archive/2011/12/09/2307905.html

第一段判断逻辑:

if和[...]用空格隔开,if是指令?"["是指令,[...]里的内容是参数,"["得与参数用空格隔开,参数之间也得用空格隔开,否则会发生不可名状的错误。

[...]内的参数"ls"是字符串,它不为空,所以输出结果为

Exist(存在)

第二段判断逻辑:

$(ls)是指令ls的输出结果,它是空,所以输出结果为

Null(空)

第三段判断逻辑:

在判断前,我们在工作目录下创建了一个文件

 $(ls)是指令ls的输出结果,它现在不为空,所以输出结果为

 Exist(存在)



关于shell脚本与shell指令:

shell翻译作壳、贝壳等,shell是用户与内核进行交互的接口

pwd、vi、gcc、sudo、mv、echo等都是shell指令

我们可以扩充shell,获得更多的shell指令。

shell脚本实际上就是有序地执行一系列shell指令,它本身也算是shell指令

使用shell指令echo在终端打印"师姐,你好!":

在安装系统的时候我们选择了简体中文语言,一般来说安装程序会为我们安装中文输入法,我们只需要按win+空格键就可以切换输入法了!

echo "师姐,你好!"

使用shell指令创建变量a并为其赋值10:

直接赋值:

a=10给a赋值10

$a 读取变量a的值

在赋值时不能随意加入空格,例如a =10,按照最开始的说法,a是指令,=10是指令a的传参

read指令赋值:

read -p "请输入一个值" a

命令的结果作为变量的值:

a=$(ls -l | grep ^- |wc -l')a的值为工作目录下普通文件的个数

其他几种赋值方式就不讨论了,因为我不会

使用shell指令cp将工作目录下的文件HW复制到其子目录文档下并命名为HWcp:

cp HW 文档/HWcp

用户目录下有一个HW文件,现在将它复制一份到文档下,并命名为HWcp

Linux系统中的文件类型及其标识符

普通文件,标识符:-

目录文件,标识符:d (Directory)

符号链接文件,标识符:l (Link)

块文件,标识符:b (Block)

管道文件,标识符:p (Pipe)

套间字,标识符:s (Socket)

使用shell指令ls -l (list -long)显示工作目录下的详细信息:

一行表示一个文件,某行首字符是此行文件的文件类型标识符

使用shell指令grep来筛选:

来自CSDN大神https://blog.csdn.net/chen1415886044/article/details/107116370

grep 师姐 师姐好.c 在师姐好.c文件中寻找含有子串"师姐"的所有行并输出到终端上:


师姐好.c文件内容
grep 师姐 师姐好.c执行后的输出结果

grep ^# 师姐好.c 在师姐好.c文件中搜索行首首字符为#的行并输出到终端上

grep ^# 师姐好.c指令输出结果

shell指令中的符号|:

|意思为将前一个指令的输出参数作为下一个指令的输入参数,例如

ls -l | grep ^-  将ls -l输出作为grep指令的第二个传参(第一个参数是^-),此指令作用是获得工作目录下普通文件的信息

ls -l | grep ^- | wc -l 此指令作用是统计工作目录下普通文件的数量

ls -l指令输出值
ls -l | grep ^-指令输出值
ls -l | grep ^- | wc -l指令输出值

更多符号的含义:来自CSDN大神https://blog.csdn.net/weixin_43972437/article/details/112606169

编写第一个shell脚本:

shell脚本的后缀名为.sh,我们使用vim编辑器创建一个名为cell0.sh的shell脚本,

第一行表示此脚本shell指令的路径

我们写下如上图的指令,$0的值是脚本本身,$1是脚本传入的第一个参数,$2是第二个........

$@的作用是显示所有传参

我们规定所有的细胞脚本的命名规则为:"cell"+"某个数字"

所以ls -l | grep cell |wc -l指令能输出工作目录下的细胞脚本总数

我们用变量N来存储工作目录下的细胞脚本数,然后保存先试着运行一下脚本

当然这时候运行脚本也可能会提示和权限有关的错误,这可能是因为我们没有这个文件的执行权限,所以它现在对于我们来说还不是可执行文件,我们用指令sudo chmod 700给用户赋予此文件的所有权限并关闭G(Group,意为自己的用户组)组和O(Other,翻译为其他)用户的权限。(注意shell脚本权限,即便脚本不具有破坏性,我们也不希望任何人都有执行它的权限)


再写一个交互指令,用read指令来读取用户的选择,并使用if语句来输出用户的选择

文章最开始已经讨论过if命令了,注意空格,==也是传参,也得用空格隔开,否则将会发生不可名状的错误

OK,写到这里,可以将这些代码都删了(除了统计细胞个数的代码),这些只是用来练练手,熟悉一下shell语法用的。

接下来来实现我们的逻辑吧!

首先写两个细胞分裂的逻辑,第一个细胞分裂是自分裂,也就是当前细胞脚本自身是否复制一份,我们用传入参数1来控制,传入"y"表示启用自分裂,否则没有动作,第二个细胞分裂是控制当前目录下所有细胞的自分裂,传入"y"表示启动所有细胞自分裂。

这两个逻辑都很简单,自分裂逻辑中还加入了数量限制

我们执行0号细胞脚本,给它传入 n y,首先它会统计当前目录下细胞个数,然后用for语句将这些细胞都启动自分裂也就是 "./cell$i.sh",这样做有一个好处,那就是新分裂的细胞不会被执行,同时刚执行0号细胞脚本时,它不会自分裂,它会在启动全局分裂时和工作目录下的其他细胞一起自分裂。

这样我们可以控制单个细胞的分裂和全部细胞的分裂。由于这样的逻辑依赖于细胞脚本的名字(主要是索引),如果在分类的过程中,用户将某些细胞删除了,此时再进行全局分裂可能出现一点小问题,所以我又加入了重排列函数,在执行自分裂前先重排列,我用第三个传参控制是否执行重排列。

将4、5号细胞移动到别的目录后,此时剩下6个细胞,再次执行全局分裂

分裂完成后有12个细胞,由于我加入了重排列逻辑,所以4、5又出现了,他们是由6、7号变的,重排列的逻辑也很简单,对!就是聪明的你所想的那样!

也可以加入定时逻辑,让分裂自动执行、让它具有周期性。

最好再加入刽子手细胞,一键即可杀死所有细胞,当然这里的空白太小了,我已经写不下了,到此为止!


ubuntu下第一个的shell脚本"细胞分裂"的评论 (共 条)

分享到微博请遵守国家法律