Shell入门指南

背景

之前写了系列的shell实战的文章,得到了挺多小伙伴的关注,遇到有些对shell不太熟悉小伙伴,所以有个想法写一篇shell入门的文章。

时间流逝,再回头去看看过去的东西,才会发现哪些东西比较重要,故撰此文,记录我在过去学习和使用shell语言过程中我个人觉得比较重要的部分,做一个小总结和分享。

文章中使用到的代码位置:https://gitee.com/dhar/YTTInjectedContentKit/tree/master/DevPods/InjectedContentKit/Example/injectContentShell

https://gitee.com/dhar/ShellLearning/tree/master/helloshell

文章内容结构如下:

语法

变量

打印

运算

控制

循环

容器

方法

文件

文件读取

文件写入

sed流编辑

模块

工具模块

流程模块

输入和菜单

获取输入

菜单

语法

变量

变量的定义

定义一个变量和其他语言的类似,shell是弱类型语言所以不需要使用类型限定,并且变量可以修改类型,下面的例子定义了一个字符串类型的变量,之后修改为数值类型

注意点:变量等号两边不能有空格出现

变量使用

变量可以赋值给另一个变量和打印,当变量被使用的时候需要在变量名称前面加上符号,还有另一种方式是把变量名放在括号中使用,可以把命令执行结果作为右值赋值给变量

打印

因为shell没有单步调试和其他功能强大的IDE,所以打印功能就经常使用到,此外打印功能还可以当做函数的返回值,比return作为函数的返回值功能更强大,shell 使用打印,内容默认输出到控制台中,可以打印字符串、变量、以及字符串中嵌入变量的混个内容,有几重要的参数选项

-e 转义字符处理,比如显示为制表符而不是显示输出

-n 把文本字符串和命令输出显示在同一行中

运算

使用执行算术运算

注意点:乘法运算符号需要转义

使用执行算术

执行算术比简单多了,并且乘法运算符号不需要转义

控制

数值比较

控制使用//语法,典型的数值比较如下

还可以使用下面的比较符号:

一个简单的9*9乘法口诀表的例子

字符串比较

文件比较

循环

C语言格式的for循环

for in 循环处理文件

文件内容如下:

while 循环

表示条件满足执行循环,比如下面的例子是9*9乘法口诀表中的一部分,表示i从1循环到9

until 循环

和相反,表示条件不满足执行循环,比如下面的例子是9*9乘法口诀表中的一部分,表示j从1循环到9

容器

数组的定义如下

注意:osx系统因为的版本太低,只能定义索引数组,在版本高于4.1的版本可以使用定义关联数组

以下的代码片定义一个数组,用于保存配置文件中的内容,然后使用for循环遍历数组内容输出到控制台。

config_content_array[$cfg_line_count]=$line 把内容保存到数组

${#config_content_array[@]} 获取数组的元素个数

config_content=$; 读取数组第i个元素

方法

方法的定义有两种方式

function func1 { #这里定义方法体 }

func2() { #这里定义方法体 }

方法返回值的处理有三种方式

return 最大返回256,表示结果码,有特殊含义,并且只能返回数值

echo 返回

保存在全局变量中

方法的参数

参数的传递添加在方法之后,多个使用空格分割

参数的获取使用$1,$2以此类推,特别地$0表示文件名、$#表示参数的个数

文件

文件读取

文件的读取可以使用命令结合循环处理

注意:$IFS是文件循环处理的分隔符,按按行处理数据需要把该值设置为,处理完成之后恢复旧值

目录的读取

文件的读取可以使用命令结合循环处理

文件写入

使用输出重定向把内容输出到文件

输出重定向符号先清空文件然后把内容写入到文件中

输出重定向符号把内容追加写入到文件中

此外可以结合其他命令实现排序、去重功能

命令对文件内容以行作为单位排序

命令对文件内容进行去重,以行为单位,一般需要结合命令使用

sed流编辑

Sed流编辑结合正则表达式可以方便的对文本文件进行查询、修改、删除、增加等操作

注意:osx系统自带的sed命令和标准的gnu-sed使用方式上有些差别,所以以下篇幅所谈论到的sed都是标准的gnu-sed,下面的这个脚本用于判断系统是否安装了gnu-sed,如果没有会自动进行安装,完成之后需要用户执行显示的命令配置下即可。

命令功能繁多,所以这里只讲讲我在实战中使用到的,首先了解小sed命令的结构

sed -param operation/pattern/replacement/flags

sed param

-e script 在处理输入时,将script中指定的命令添加到已有的命令中

-f file 在处理输入时,将file中指定的命令添加到已有的命令中

-n 不产生命令输出,使用print命令来完成输出

-i 把修改写入到原文件中

sed operation

s 替换

a 追加

d 删除

sed pattern/replacement

查找对应的模式和匹配模式的替换内容

sed flag

有4种可用的替换标记:

数字,表明新文本将替换第几处模式匹配的地方;

g,表明新文本将会替换所有匹配的文本;

p,表明原先行的内容要打印出来;

w file,将替换的结果写到文件中。

sed添加内容

以下是injectContentShell#脚本文件中的代码片段,使用操作吧内容添加到方法的开头

这部分是,匹配OC中方法的开始

这部分是,注意其中插入内容的变量要使用双引号和单引号包含处理

sed删除内容

以下是injectContentShell#脚本文件中的代码片段,使用操作删除内容

sed修改替换内容

以下是injectContentShell#脚本文件中的代码片段,使用操作替换内容,有以下几个要点

,使用操作,注意和中变量的处理方式,使用双引号、单引号双重包含,使用为表示全部替换

,命令查找文件夹下所有出现内容的文件,选项表示递归查找,选项表示只显示匹配到的文件,返回的结果可能是多个的。

模块

shell是面向过程的语言,不具备面向对象的特性,shell可以把部分功能独立分离出来,放在单独的脚本文件中,其他模块可以导入该脚本文件,使用其中的功能,这就是shell的伪面向对象

工具模块

工具模块是包含了工具方法的模块,比如数学计算可以放在一个单独的文件中独立为一个模块,其他需要使用到的地方引入这个模块,使用其中定义的方法即可

保存了一些数学计算函数

其他模块使用包含这个模块,可以调用其中定义的power方法

注意:中是的简写,这里也可以写成

流程模块

流程模块是包含了一些列操作的模块,可以向该模块传递参数,也可以有返回值。流程模块中有两个地方比较特别,一个是流程模块本身参数的处理方式和外部调用流程模块传入参数的方式

流程模块处理参数

流程模块处理参数使用命令实现,其中格式,和之后的表示指定选项和选项需要有参数,第一个表示忽略错误,使用case分支处理参数选项对应的参数值。

参数的传递

参数的传递和使用命令行的选项类似,可以在选项后面添加该选项的参数值

下面定义的是一个流程模块的脚本文件,是injectContentShell#脚本文件中的代码片段,实现了功能,可以传递两个参数。

在另一个模块中使用流程模块

输入和菜单

获取输入

下面是一个循环的输入和检测输入是否是合法目录的例子,是injectContentShell#脚本文件中的代码片段

是输入的提示,表示不换行,用户的输入跟随在提示后面

把用户的输入内容保存在变量path中

菜单

在脚本中可能会有使用菜单选项进行交互的场景,有以下几个要点

命令中用了-n选项来限制只读取一个字符。这样用户只需要输入一个数字,也不用按回车键,输入的内容保存在变量中

命令是用来清空命令行的屏幕的

-e 选项用来处理转义字符

-n 选项让光标处于同一行,用户的输入会显示在同一行

使用循环获取用户的输入,在循环中使用分支处理不同的操作

以下脚本是injectContentShell#文件中的一部分

希望本文对你有帮助,求帮转,谢谢

公众号推荐:

公众号:VOA英语每日一听

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180421B06MIN00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券