微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Shell脚本

··········1.有哪些编程语言?

1.机器语言 0 和1 构成

2.汇编语言

在这里插入图片描述

3.高级语言 c java shell phy 等都是高级语言

编译型: 编译 -》 翻译 -》 计算机 跨平台性差 执行速度快 C C++
解释型: 解释性 -》解释器 -》翻译 -》计算机 跨平台性强 执行速度慢 Shell Python PHP ruby

在这里插入图片描述

机器语言: 优点是最底层,速度最快,缺点是最复杂,开发效率最低
汇编语言: 优点是比较底层,速度最快,缺点是最复杂,开发效率最低
高级语言: 编译型语言执行速度快,不依赖语言环境运行,跨平台差
解释型语言跨平台好,一份代码,到处使用,缺点是执行速度慢,依赖解释器运行

··········2.Shell如何执行用户的指令?

Shell有两种执行指令的方式
1.第一种方法用户事先编写一个sh脚本文件,内含Shell脚本,而后使用Shell程序执行该脚本,这种习惯称为 Shell编程;
2.第二种是用户直接在Shell界面上执行Shell命令,由于Shell界面的关系,大家习惯一行一行的书写,很少写出成套的程序一起执行,所有也称为命令行;

总结:
Shell只是为用户与机器之间搭建建成的一个桥梁,让我们能够通过Shell来对计算机进行操作和交互。从而让计算机为我们服务的目的。

··········3.Shell分类

Linux认的Shell是 /bin/bash
流行的Shell有ash,bash,ksh,csh,zsh等,不同的Shell都有自己的特点以及用途

1./bin/bash

2.csh
c Shell 使用的是类"c"语法,是具有c语言风格的一种Shell,其内部命令有52个,较为庞大,目前使用的并不多,已经被/bin/tcsh所取代
3.ksh
Korn Shell的语法与Bourne Shell相同,同时具备了C Shell的易用特点,许多安装脚本都使用Ksh,ksh有42条内部命令,与bash相比有一定的限制性。
4.tcsh
tcsh是csh的增强版,与C Shell完全兼容
5.sh
一个快捷方式,已经被/bin/bash所取代
6.nologin
用户不能登录
7.zsh
目前Linux里面最庞大的一种 zsh. 它有84个内部命令,使用起来也比较复杂,一般情况下,不会使用该Shell

4. bash一些基础特性(自动补全,历史记忆,别名)

·····4.1 bash-complete自动补全脚本

自动补全脚本 bash-completion
如果没有就使用下面命令安装
yum install -y bash-completion

在这里插入图片描述

注意: 重启系统后可正常补齐
认情况下,bash为linux用户提供了以下补齐功能
1.变量补全
2.用户名补全
3.主机名补全
4.路径补全
5.文件名补全

·····4.2 history命令历史记忆功能

Bash有自动记录命令的功能自动记录到.bash_history隐藏文件中,还可以在下次需要直接调用历史记录中的命令
1.查询之前使用的所有命令
history

在这里插入图片描述

2.查询最近的N个命令
history n

在这里插入图片描述


3.删除相应的第n个命令
history -d n

在这里插入图片描述


4.指定执行命令历史中的第N条语句

在这里插入图片描述


5.指定执行命令历史中的倒数第N条语句
! -n
6.指定执行命令历史中的最后一条语句
!!
7.指定执行命令历史中的最近一条以[String]开头的语句
![String]
8.将命令历史写入命令历史的文件
history -w

9.回显 echo 之后的语句,而使用 echo $FILENAME 命令可以查看file所在路径
echo $filename

10.查看命令历史的内容
cat ~/.bash_history

11.删除所有的命令历史记录
history -c

·····4.3 alias别名功能

alias命令,别名的好处是可以把本来很长的指令简化缩写,来提高工作效率;
alias #查看当前系统所有的别名

在这里插入图片描述


alias bd=‘curl www.baidu.com’
#定义新的别名,这时候输入h5就等于输入 ‘curl www.baidu.com’
unalias bd #取消别名定义

在这里插入图片描述


如果想要文件永久生效,只需将上述别名命令写到对应用户或者系统bashrc文件

在这里插入图片描述


注意,不管修改了什么系统配置文件,记得 source 刷新以下
这里是 source ~/.bashrc

在这里插入图片描述


如果想要真实命令可以在命令前面添加反斜杠,使别名失效

在这里插入图片描述

··········5.Shell环境变量

bash的初始化
1. /etc/profile 全局(公有)配置,不管是哪个用户登录时都会读取该配置文件
2. /ect/bashrc
全局,使用脚本时会读取该配置,这个只是在centos系统中才有,在Ubuntu就没有
在Ubuntu里面与之对应的是/etc/bash.bashrc
bash执行时,不管是何种方式,都会读取此文件
3.~/.profile
若bash是以login方式执行时,读取/.bash_profile,若它不存在,则读取/.bash_login,若它不存在,则
读取~/.profile
图像模式登陆时,此文件将会被读取,即使存在/.bash_profile和/.bash_login
4.~/bash_login
若bash是以login方式执行时,读取/.bash_profile,若它不存在,则读取/.bash_login,若前两者不存在,
则读取~/.profile
5.~/.bash_profile
Unbutu认没此文件,可新建;只有bash是以login形式执行时,才会读取此文件,通常该配置会取读~/.bashrc
6.~/.bashrc
当bash是以non-login 形式执行时,读取此文件,若是以login形式执行,则不会读取此文件;

  1. /etc/profile
    
  2. /etc/bashrc
    
  3. ~/.profile
    
  4. ~/.bash_login
    
  5. ~/.bash_profile
    
  6. ~/.bashrc
    
  7. ~/.bash_logout

图形化界面时 1 3
图形化界面后,打开终端时: 2 6
文件界面时: 2 1 6
su: 2 1 5
2 6

··········6.Shell特性

6.1 快捷键

ctrl+A
把光标移动到命令行开头,如果我们输入的命令过长,想要把光标移动到命令行开头时使用;
ctrl+E
把光标移动到命令行结尾
ctrl+C
强制终止命令
ctrl+L
清屏,相当于clear命令
ctrl+U
删除或剪切光标之前的命令;我输入了一行很长的命令,不用使用退格健一个一个字符的删除
使用这个快捷键会更加方便
ctrl+K
删除或剪贴光标之后的内容
ctrl+Y
粘贴 ctrl+U或ctrl+K剪贴的内容
ctrl+R
在历史命令中搜索,按下ctrl+R之后,就会出现搜索界面,只要输入搜索内容,就会从历史命令中搜索
ctrl+D
退出当前终端
ctrl+Z
暂停,并放入后台,这个快捷键牵扯工作管理的内容,我们在系统管理章节详细介绍。
ctrl+S
暂停屏幕输出
ctrl+Q
恢复屏幕输出

小火车快捷键
安装 yum -y install sl 输入sl就可以看到了

6.2 前后作业命令

几个常用的作业命令

command & 直接让作业进入后台运行 比如 sl & 就是让小火车后台运行
ctrl+z 将当前作业切换到后台
jobs 查看后台作业状态
fg %n后台运行的作业n切换到前台
bg %n 让指定的作业n在后台运行
kill %n 移除指定的作业n
n"为jobs命令查看到的jobs编号,不是进程Id
一个job会有一个对应的job编号,编号从当前的终端从1开始分配
job编号的使用样式为[n],后面可能会跟有”+“号或者”-"号,或者什么也不跟。
"+"号表示最近的一个job
"-"号表示倒数第二个被执行的job
注: "+“号与”-"号会随着作业的完成或添加而动态的发生变化
通过jobs方式来管理作业,当前终端的作业在其他终端不可见

在这里插入图片描述

6.3 输入输出重定向

一般情况下:
输入方向就是数据从哪里流向程序。数据认从键盘流向程序,如果改变了他的方向,数据就从让其他地方流入,这就是输入重定向;
输出方向就是数据从程序流向哪里。数据认从程序流向显示屏,如果改变了它的方向,数据就流向其他地方,这就是输出重定向;

Linux中一切皆文件包括标准输入设备(键盘)和标准输出设备(显示器)在内的所有计算机硬件都是文件;
为了表示和区分已经打开的文件,Linux会给每一个文件分配一个ID,这个ID就是一个整数,被称为文件描述符;

输出重定向是指命令的结果不再输出显示屏上,而是输出到其他地方,一般是文件中,这样做的最大好处就是
把命令的结果保存起来,当我们需要的时候可以随时查询.Bash支持输出重定向符号如下表所示:
1.标准输出重定向 command > file
作用: 以覆盖的方式,把command的正确输出结果输出到file文件中;
command >>file
作用: 以追加的方式,把command的正确输出结果输出到file文件
2.标准错误输出重定向 command 2> file
作用: 以覆盖的方式,把command的错误信息输出到file文件
command 2>>file
作用: 以追加的方式,把command的错误信息输出到file文件
3.正确输出错误信息同时保存 command> file 2>&1
作用: 以覆盖的方式,把正确输出错误信息同时保存到同一个文件file中
command >>file 2>&1
作用: 以追加的方式,把正确输出错误信息同时保存到同一个文件file中

注意: 输出重定向> 代表的是覆盖>>代表的是追加
输出重定向的完整写法其实是 fd>file 或者 fd>>file ,其中 fd表示文件描述符,如果不写,认为1,也就是标准输出文件
文件描述符为1时,一般省略不写,如上表所示,当然,如果你愿意,
也可以将command >file写作command 1>file,但这样做是多此一举
文件描述符大于1的值时,比如2,就必须写上。
需要重点说明的是,fd和>之间不能有空格,否则Shell会解析失败; >和file之间的空格可有可无。
为了保持一致,习惯在>两边都不加空格.
ls / &>/dev/null 解释: & 代表正确和错误都包含 /dev/null相当于linux的垃圾回收器,无穷大
输入重定向就是改变输入的方向,不再使用键盘作为命令输入的来源,而是使用文件作为命令的输入。
command <file 将file文件中的内容作为command的输入
command <<END 从标准输入(键盘)中读取数据,知道遇见分界符END才停止(分界符可以是任意的字符串,用户自己定义).
command file2 将file1作为command的输入,并将command的处理结果输出到file2.
举例: wc -l filename 统计文件的行数
wc -l << END wc命令会一直等待输入,直到遇见分节符为止,这里是END
文件输入
几个基本符号以及其含义
/dev/null表示空设备文件,相当于window里面的垃圾箱,无穷大
0表示stdin标准输入
1表示stdout标准输出
2表示stderr标准错误

认为标准输出重定向 与1>相同
2>&1 意思是把标准错误输出重定向到标准输出
&>file 意思是把标准输出和标准错误输出重定向文件file中
&file意思是把标准输出和标准错误输出重定向文件file中

/dev/null

如果不想把命令的输出结果保存到文件,也不想把命令的输出结果显示在屏幕上,干扰命令的执行,可以把命令的所有结果重定向到/dev/null文件
ls -l &>/dev/null
可以把/dev/null当成Linux系统的垃圾箱,任何放入垃圾箱的数据都会被丢弃,不能恢复

6.4 tee管道

1.管道|
管道,从一头进去,从另外一头出来。
在Shell中,管道将一个程序的标准输出作为另外一个程序的标准输入,就像用一根管子将一个程序的输入连接到另外一个程序的输入一样;
管道的符号是|,下面的程序将man的标准输出作为less的标准输入,以实现翻页功能

man ls | less

2.tee
有时候我们想要同时将程序输出显示在屏幕上(或进入管道)和保存到文件中,这个时候可以使用tee
tee程序的输出和它的输入一样,但是会将输入内容额外的保存到文件中;

cat /etc/passwoed |tee hello.txt

tee程序将cat程序的输出显示在屏幕上,并且在hello.txt文件中保留了副本,需要注意的是,如果tee命令中指定的文件已经存在,那么它将会被覆盖,使用 -a选项在文件末尾追加内容(而不是覆盖)

cat /etc/passwoed |tee -a hello.txt

6.5 命令排序

&& || 具备逻辑判断

&& command1 && command2 当命令1执行成功了才会执行命令2

在这里插入图片描述


|| command1 || command2
如果命令1成功就直接打印出来,如果命令1失败了才会执行命令2

在这里插入图片描述


常用于:当执行某个命令失败时就安装该命令

在这里插入图片描述


; (分号)不具备逻辑判断,其实就是连接2条执行的命令,不具备逻辑判断

在这里插入图片描述

6.6 通配

* 匹配0个或多个任意字符

eg: a*b a与b之间可以存在0或多个字符 ab aabb azsb …
? 匹配一个任意字符
eg: a?b a与b之间有且仅存在一个字符 a1b adb …
[list] 匹配list中的任意单个字符
eg: a[xyz]b a与b之间必须但也只能存在一个字符,该字符只能是x或y或z 例如: axb ayb azb
[!list] 匹配除list中的任意单个字符
eg: a[!a-z]b a与b之间必须但只能存在单个字符,且这个字符不可以是小写字母 列如: aAb
[c1-c2] 匹配c1-c2之间的任意单个字符
eg: a[0-1]b a与b之间必须但只能存在一个字符,该字符只能是数字 列如: a0b a1b
{string1,string2,string3} 匹配string1,string2等中的一个字符串
eg: a{abc,xyz,opq} a与b之间必须但只能存在一个字符串,该字符串只能是abc,xyz,opq

··········7.Shell特性

7.1 代码风格规范

开头有"蛇棒"所谓shebang其实就是在很多脚本的第一行出现的以"#!"开头的注释,它指明了当我们没指定解释器的时候认的解释器,一般有以下几种:
#! /bin/sh
#! /bin/bash 等等

在这里插入图片描述


直接使用./a.sh来执行脚本的时候,如果没用shebang,就会认用$shell指定的解释器,否则就会用shebang指定的解释器。也可以用下面的方式来指定

#! /usr/bin/env bash

7.2 代码要有注释

注释,显然是一个常识,不过这里还是要再强调一下,这个在shell脚本里尤为重要。因为很多单行的shell命令不是那么浅显易懂,没有注释的话在维护起来会让人尤其的头大。
  注释的意义不仅在于解释用途,而在于告诉我们注意事项,就像是一个README。
  具体的来说,对于shell脚本,注释一般包括下面几个部分:
shebang
脚本的参数
脚本的用途
脚本的注意事项
脚本的写作时间,作者,版权等
各个函数前的说明注释
一些较复杂的单行命令注释

7.3 参数要规范

这一点很重要,当我们的脚本需要接受参数的时候,我们一定要先判断参数是否合乎规范,并给出合适的回显,方便使用者了解参数的使用。
  最少,最少,我们至少得判断下参数的个数吧:
  参数要规范:
if [[$# !=2]];then
echo “Parameter incorrect”
exit 1
fi

7.4 变量

一般情况下我们会将一些重要的环境变量定义在开头,确保这些变量的存在。
source /etc/profile
export PATH=”/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/apps/bin/”

这种定义方式一个很常见的用途,最典型的应用就是,当我们本地安装了很多java版本时,我们可能需要指定一个java来用。那么这时我们就会在脚本开头重新定义JAVA_HOME以及PATH变量来进行控制。
  同时,一段好的代码通常是不会有很多硬编码在代码里的“魔数”的。如果一定要有,通常是用一个变量的形式定义在开头,然后调用的时候直接调用这个变量,这样方便日后的修改

7.5 缩进

在这里插入图片描述

7.6 命名有标准

在这里插入图片描述

7.7 编码要统一

在这里插入图片描述

7.8 权限记得加

在这里插入图片描述


在这里插入图片描述

7.8.1 chmod a+x

chmod a+x的含义

版权

u 表示用户
g 表示用户
o 表示其它
a 表示所有

chmod a+x a.txt 等价于 chmod +x a.txt 给所用户给予a.txt文件可执行权限

chmod u+x a.txt a.txt文件的所有用户可执行权限

chmod g+x a.txt a.txt用户组可执行权限

chmod o+x a.txt a.txt其他用户可执行权限

7.9 日志和回显

在这里插入图片描述

7.10 密钥要移除

在这里插入图片描述

7.11 太长要分行

在这里插入图片描述

7.12 学会查路径

很多情况下,我们会先获取当前脚本的路径,然后一这个路径为基准,去找其他的路径。通常我们是直接用pwd以期获得脚本的路径。
  不过其实这样是不严谨的,pwd获得的是当前shell的执行路径,而不是当前脚本的执行路径。
  正确的做法应该是下面这两种:

script_dir=$(cd $(dirname KaTeX parse error: Expected 'EOF', got '&' at position 4: 0) &̲& pwd) script_…(dirname $(readlink -f $0 ))

在这里插入图片描述


 应当先cd进当前脚本的目录然后再pwd,或者直接读取当前脚本的所在路径。

7.13 代码要简短

在这里插入图片描述

7.14 代码有效率

在使用命令的时候要了解命令的具体做法,尤其当数据处理量大的时候,要时刻考虑该命令是否会影响效率。
  比如下面的两个sed命令:

在这里插入图片描述


他们的作用一样,都是获取文件的第一行。但是第一条命令会读取整个文件,而第二条命令只读取第一行。当文件很大的时候,仅仅是这样一条命令不一样就会造成巨大的效率差异。
  当然,这里只是为了举一个例子,这个例子真正正确的用法应该是使用 head -n 1 file 命令。。。
  勤用双引号
  几乎所有的大佬都推荐在使用”$”来获取变量的时候最好加上双引号。
  不加上双引号在很多情况下都会造成很大的麻烦,为什么呢?举一个例子:
  

在这里插入图片描述


 他的运行结果如下:
 

在这里插入图片描述


为啥会这样呢?其实可以解释为它执行了下面的命令:就是一个是打印出字符串一个是打印出所有脚本

在这里插入图片描述


在这里插入图片描述

在很多情况下,在将变量作为参数的时候,一定要注意上面这一点,仔细体会其中的差异。上面只是一个非常小的例子,实际应用的时候由于这个细节导致的问题实在是太多了。。。
  巧用main函数
  我们知道,像java,C这样的编译型语言都会有一个函数入口,这种结构使得代码可读性很强,我们知道哪些直接执行,那些是函数。但是脚本不一样,脚本属于解释性语言,从第一行直接执行到最后一行,如果在这当中命令与函数糅杂在一起,那就非常难读了。
  用python的朋友都知道,一个合乎标准的python脚本大体上至少是这样的:
  

在这里插入图片描述


 他用一个很巧妙的方法实现了我们习惯的main函数,使得代码可读性更强。
  在shell中,我们也有类似的小技巧:
  

在这里插入图片描述


我们可以采用这种写法,同样实现类似的main函数,使得脚本的结构化程度更好。
  考虑作用域
  shell中认的变量作用域都是全局的,比如下面的脚本:
  

在这里插入图片描述


他的输出结果就是2而不是1,这样显然不符合我们的编码习惯,很容易造成一些问题。
  因此,相比直接使用全局变量,我们最好使用local readonly这类的命令,其次我们可以使用declare来声明变量。这些方式都比使用全局方式定义要好。
  巧用heredocs
  所谓heredocs,也可以算是一种多行输入的方法,即在”<<”后定一个标识符,接着我们可以输入多行内容,直到再次遇到标识符为止。
  使用heredocs,我们可以非常方便的生成一些模板文件
  

在这里插入图片描述

7.15 使用新的写法

在这里插入图片描述

7.16 其他小 Tip

考虑到还有很多零碎的点,就不一一展开了,这里简单提一提。

1.路径尽量保持绝对路径,不容易出错,如果非要用相对路径,最好用./修饰
2.优先使用bash的变量替换代替awk sed,这样更加简短
3.简单的if尽量使用&& ||,写成单行。比如[[ x > 2]] && echo x
4.当export变量时,尽量加上子脚本的namespace,保证变量不冲突
5.会使用trap捕获信号,并在接受到终止信号时执行一些收尾工作
6.使用mktemp生成临时文件文件
7.利用/dev/null过滤不友好的输出信息
8.会利用命令的返回值判断命令的执行情况
9.使用文件前要判断文件是否存在,否则做好异常处理
10.不要处理ls后的数据(比如ls -l | awk ‘{ print $8 }’), ls的结果非常不确定,并且平台有关
11.读取文件时不要使用for loop而要使用while read

··········8.Shell脚本调试

Shell脚本的语法调试,使用bash的相关参数进行调试

sh [参数] 文件名.sh

-n 不要执行script,仅查询语法
-v 在执行script之前,先将script的内容输出到屏幕上
-x 将使用的脚本的内容输出到屏幕,该参数经常被使用

执行脚本有以下方式,使用工作目录方式执行脚本需要加权限 认开全部权限

在这里插入图片描述


除了脚本sh bash 执行以及工作目录执行外,在shell环境下也可以使用shell环境执行

在这里插入图片描述


Shell 环境执行

在这里插入图片描述

··········9.作业脱机管理nohup

nohup

将作业(进程)切换到后台可以避免由于误操作如[ctrl]+c等导致的job被异常中断的情形,而脱机管理主要是针对终端异常断开的情形。

通常使用nohup命令来使得脱机或注销之后,Job依旧可以继续运行。也就是说nohup忽略所有挂断(SIGHUP)信号。

如果该方式命令之后未指定&符号,则job位于前台,指定&符号,则job位于后台

下面是使用nohup方式且将Job放入后台处理,同时指定了日志文件,则nohup使用指定的日志文件
而不会输出到缺省的nohup.out

eg:

启动进程
nohup java -jar babyshark-0.0.1-SNAPSHOT.jar > log.file 2>&1 &

··········10.Screen

在这里插入图片描述


官方网址:http://www.gnu.org/software/screen/

1、简介

Screen是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能
在Screen环境下,所有的会话都独立的运行,并拥有各自的编号、输入、输出和窗口缓存。用户可以通过快捷键在不同的窗口下切换,并可以自由的重定向各个窗口的输入和输出

2、语法

$> screen [-AmRvx -ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s ][-S <作业名称>]

-A  将所有的视窗都调整为目前终端机的大小。

-d <作业名称>  将指定的screen作业离线。

-h <行数>  指定视窗的缓冲区行数。

-m  即使目前已在作业中的screen作业,仍强制建立新的screen作业。

-r <作业名称>  恢复离线的screen作业。

-R  先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业。

-s  指定建立新视窗时,所要执行的shell。

-S <作业名称>  指定screen作业的名称

-v  显示版本信息。

-x  恢复之前离线的screen作业。

-ls或–list  显示目前所有的screen作业。

-wipe  检查目前所有的screen作业,并删除已经无法使用的screen作业。

3、常用screen参数

screen -S yourname -> 新建一个叫yourname的session

screen -ls -> 列出当前所有的session

screen -r yourname -> 回到yourname这个session

screen -d yourname -> 远程detach某个session

screen -d -r yourname -> 结束当前session并回到yourname这个session

4、在Session下,使用ctrl+a(C-a)

C-a ? -> 显示所有键绑定信息

C-a c -> 创建一个新的运行shell的窗口并切换到该窗口

C-a n -> Next,切换到下一个 window

C-a p -> PrevIoUs,切换到前一个 window

C-a 0…9 -> 切换到第 0…9 个 window

Ctrl+a [Space] -> 由视窗0循序切换到视窗9

C-a C-a -> 在两个最近使用的 window 间切换

C-a x -> 锁住当前的 window,需用用户密码解锁

C-a d -> detach,暂时离开当前session,将目前的 screen session (可能含有多个 windows) 丢到后台执行,并会回到还没进 screen 时的状态,此时在 screen session 里,每个 window 内运行的 process (无论是前台/后台)都在继续执行,即使 logout 也不影响。

C-a z -> 把当前session放到后台执行,用 shell 的 fg 命令则可回去。

C-a w -> 显示所有窗口列表

C-a t -> time,显示当前时间,和系统的 load

C-a k -> kill window,强行关闭当前的 window

C-a [ -> 进入 copy mode,在 copy mode 下可以回滚、搜索、复制就像用使用 vi 一样

C-b Backward,PageUp

C-f Forward,PageDown

H(大写) High,将光标移至左上角

L Low,将光标移至左下角

0 移到行首
$ 行末
w forward one word,以字为单位往前移
b backward one word,以字为单位往后移
Space 第一次按为标记区起点,第二次按为终点
Esc 结束 copy mode
C-a ] -> paste,把刚刚在 copy mode 选定的内容贴上

5、常用操作

创建会话(-m 强制):
screen -dmS session_name

session_name session名称

关闭会话:

screen -X -S [session # you want to kill] quit

查看所会话:

screen -ls

进入会话:

screen -r session_name

··········11. shell变量

11.1 自定义变量

自定义变量: 变量名=变量值 变量名必须以字母或下划线开头 区分大小写

查看变量 echo $变量名
取消变量 unset 变量名
作用范围 仅在当前窗口shell中有效

自定义变量abc=aaaabbbcccc
打印变量 echo $abc
也可以打印pwd 只不过需要添加反斜杠
取消自定义变量 unset 变量名
如果新开一个窗口或者取消自定义变量,则失效

在这里插入图片描述

11.2 环境变量

环境变量
其实就是 /etc/profile
~/.bashrc 等

在这里插入图片描述

11.3 位置变量

定义一个脚本 ,$1 $2 $3

在这里插入图片描述


当给3个参数赋值时,会给1 2 3 赋值,但是不足3个,就从上到下赋值,根据顺序赋值而不是数字

在这里插入图片描述

11.4 预定义变量

1、$# 表示参数个数。

2、$0 是脚本本身的名字。

3、$1 是传递给该shell脚本的第一个参数。

4、$2 是传递给该shell脚本的第二个参数。

5、$@ 表示所有参数,并且所有参数都是独立的。

6、$$ 是脚本运行的当前进程ID号。
$! 上一个后台进程的PID

7、 $?显示最后命令的退出状态,0表示没有错误,其他表示有错误

8 、 $* 将所有参数作为一个整体

··········12 shell变量赋值方式

1.显示赋值
变量名=变量值

ip1=192.168.1.251
school=“beijing”
today=date +%F
today=$(date +%F)

read 变量名
read -p “提示信息” 变量名
read -t 5 -p “提示信息” 变量名 -t 5 意思是5秒不输入算超时
read -n 2 变量名 -n 代表字符数量 -n 2 代表2个字符

在这里插入图片描述


在这里插入图片描述


""代表强引用
''代表弱引用

·········· 13 shell变量运算

整数运算

13.1 方法一: expr + - * % 注意空格必须要有

在这里插入图片描述


在这里插入图片描述

13.2 方法二: $(())

其实就是把expr换成双括号的形式,另外一般搭配echo使用,
直接使用命令是打印不出来的

在这里插入图片描述

13.3 方法三: $[] 雷同方法

在这里插入图片描述

13.4 方法四: let

在这里插入图片描述


小数运算

echo “2*4”|bc 2乘以4等于8
echo “2^4”|bc 2的四次方等于16

在这里插入图片描述


echo “scale=2;6/4” |bc scale的意思是保留小数点2位

在这里插入图片描述


awk ‘BEGIN{print 1/2}’

在这里插入图片描述

··········14 内容替换与删除

"消除"

在这里插入图片描述


索引以及切片

在这里插入图片描述


替换

在这里插入图片描述


在这里插入图片描述

··········15 函数

可以带function fun()定义 ,也可以直接fun() 定义,不带任何参数

#方法

function name{
commands
[return value]
}

#方法

name(){
commands
[return value]
}

#方法

function name{
commands
[return value]
}

function 是shell中的关键字,专门用来定义函数;
name是函数名;
commands是函数要执行的代码
return value表示函数的返回值,其中return 是shell关键字,专门用在函数中返回一个值;
这一部分可以写也可以不写。
由{}包围的部分称为函数体,调用一个函数,实际上就是执行函数体中的代码
函数的优势
方便n次使用,减少代码量,使之方便,简洁。
当需要修改里面的重复代码时,只需要修改一次函数即可实现需求;
函数写进文件,需要时直接通过文件调用

执行带参数的函数
functionName arg1 arg2
Shell中的位置参数(1/2…/?/$@)均可作为函数的参数进行传递
@$0比较特殊,仍然是父脚本的名称
此时父脚本的参数会临时被函数的参数所掩盖或隐藏
函数的参数变量是在函数里面进行定义

在这里插入图片描述

15.1 参数传递

在这里插入图片描述

15.2 return返回函数结果

在这里插入图片描述

15.3 从文件调用函数

在这里插入图片描述


在这里插入图片描述

15.4 全局变量和局部变量

在这里插入图片描述


在这里插入图片描述

15.5 数组变量和函数

在这里插入图片描述

15.6 递归函数

在这里插入图片描述


在这里插入图片描述

15.7 for循环语法结构

for循环的语法结构

for  变量  in  值集合
do
   执行命令
done

—案列1 创建文件夹----
eg: 因为刚开始不确定是否存在目录所以加-p

   for  i  in {1..10}
   do
       mkdir -p /datas/demo$i
       for o in {1..10}
       do
         mkdir  /datas/demo$i/test$o
       done
   done

在这里插入图片描述


也可以使用下面的方式
eg: 因为刚开始不确定是否存在目录所以加-p

  for  i  in $(seq 1 10)
   do
       mkdir -p /datas/demo$i
       for o in $(seq 1 10)
       do
         mkdir  /datas/demo$i/test$o
       done
   done

在这里插入图片描述


–案列2 计算目录的大小----

在这里插入图片描述

15.8 while循环语句结构

while 条件测试
do
执行命令
done

while语法说明,while首先进行条件测试,如果传回值为0(条件测试为真),
则进入循环,执行命令区域,否则不进入循环。
满足while测试条件,执行命令区域,直到while的测试条件不满足结束执行
while循环(如果条件一直满足执行无穷循环)
==实列1:

#! /bin/bash
while read a       #使用read有标准输入读取数据,赋值变量demo中,如果读取的数据非空,就进入循环
 do                  ,现实读取到的内容
   echo $a
done < /datas/6files

#!/bin/bash
while read demo
do
 echo ${demo}
done < /home/srcipts/testfile #将/home/scipts/testfile的内容按行输入给read读取

=实列2:

#! /bin/bash
declare -i i=1    #声明设置i和sum为整数型
declare -i sum=0
while ((i<=10))  #while条件测试,只要i值小于或等于10,就执行循环
do
   let sum+=i   #sum+=i 和sum=sum +i 是一样的,sum累加i
   let i++     #let i++, i的值递增,此行是改变条件测试的命令
done          # 遇到done,回到while条件测试
echo $sum     # 直到while条件不满足,显示sum的值

15.9 until循环语句

Shell循环until语句
while循环的条件测试是测试真值,until循环则是测试假值

until循环的语法结构
until 条件测试
do
  执行命令
done
#!/bin/bash
declare -i i=10         #声明i和sum为整数型
declare -i sum=0
until ((i>10))          #条件测试:只要i值未超过10,就进入循环
do
  let sum+=i           #sum+=i和sum=sum+i是一样的,sum累加上i
  let ++i              #i的值递增1,此行是改变条件测试的命令,一旦i大于10,可终止循环
done                   #遇到done ,回到until条件测试
echo $sum              #直到until的条件满足显示sum的值

15.10 Shell循环控制

Shell循环控制
break continue exit 一般用于循环结构中控制循环的走向

break n n表示退出循环的次数,如果省略n表示跳出整个循环
continue n表示退到第n层继续循环,如果省略n表示跳过本次循环进入下一次循环
exit n 退出当前的shell程序,并返回n,n也可以省略
return 用于返回一个退出值给调用函数
shift 用于将参数列表list左移指定次数,最左端的那个参数就从列表中删除,其后边的参数 进入循环

15.11 Shell测试表达式

15.11.1 test测试表达式

test测试表达式,利用test命令进行条件测试表达式,test命令与测试表达式之间至少有一个空格

[测试表达式] 通过[]中括号进行条件测试表达式,[]中括号边界与测试表达式之间至少有一个空格
[[测试表达式]] 通过[[]]双括号进行条件测试表达式,[[]]双括号与测试表达式之间至少有一个空格
((测试表达式)) 通过(())双小括号进行条件测试表达式,(())双小括号两端不需要空格,常用于整数对比

$[] 整数运算
$() 命令替换 shell会执行括号的cmd,然后将结果作为变量进行替换,替换只能替换标准输出错误输出不能替换
${} shell中变量的原型,用于限定变量名称的范围,并且支持通配
[] 条件测试
() 子shell中执行
{} 在当前shell执行

#()是重新开一个子shell然后执行,而{}则是在当前shell里执行
#()最后一个命令可以不用分号,{}最后一个命令要用分号。
#()里第一个命令和左边括号不必有空格,而{}第一个命令和左括号之间必须有一个空格

在这里插入图片描述

#()和{}里的某个命令的重定向会影响该命令,而{}里的会影响内外的所有命令

在这里插入图片描述

15.11.2 文件测试表达式

linux 下表达式
文件表达式
-e filename 如果 filename文件不管是文件还是目录只要存在,则为真
-d filename 如果 filename文件存在且为目录,则为真
-f filename 如果 filename为常规文件且存在,则为真
-L filename 如果 filename为符号链接,则为真
-r filename 如果 filename文件存在且有可读权限,则为真
-w filename 如果 filename文件存在且有可写权限,则为真
-x filename 如果 filename文件存在且有可执行权限,则为真
-s filename 如果文件文件文件大小不为0,则为真
-h filename 如果文件是软链接,则为真
filename1 -nt filename2 如果 filename1比 filename2新,根据文件修改之间计算,则为真。
filename1 -ot filename2 如果 filename1比 filename2旧,根据文件修改之间计算,则为真。

在这里插入图片描述


整数变量表达式
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于

字符串变量表达式

If [ $a = $b ] 如果string1等于string2,则为真 ,字符串允许使用赋值号做等号
if [ $string1 != $string2 ] 如果string1不等于string2,则为真
if [ -n $string ] 如果string 非空(非0),返回0(true)
if [ -z $string ] 如果string 为空,则为真
if [ $sting ] 如果string 非空,返回0 (和-n类似)

逻辑与-a 条件表达式的并列
if[表达式1 -a 表达式2]

逻辑或-o 条件表达式的或
if[表达式1 -o 表达式2]

在这里插入图片描述

15.11.3 字符串测试表达式

字符串测试表达式
参数 功能
-z s1 如果字符串s1的长度为0,则测试条件为真
-n s1 如果字符串s1的长度大于0,则测试条件为真
sl 如果字符串s1不是空字符串,则测试条件为真
=或== s1=s2 如果s1等于s2,则测试条件为真,"="前后应有空格
!= s1!=s2 如果s1不等于s2,则测试条件为真
< s1 如果按照字典顺序s1在s2之前,则测试条件为真
> s1>s2 如果按自定义顺序s1在s2之后,则测试条件为真

在这里插入图片描述


注意
对于字符串的比较,一定要将字符串加比引号后再比较,如[ -n “$string”]
=与!=可用于判断两个字符串是否相同

在这里插入图片描述

15.11.4 数值测试表达式

整数操作符
在[]和test中使用 在[[]]和(())中使用 说明
-eq ==或= 等于,全拼为equal
-nq != 不等于,全拼为not equal
-gt > 大于,全拼为greater than
-ge >= 大于等于 greater equal
-lt < 小于,全拼为less than
-le <= 小于等于,全拼为 less equal

在这里插入图片描述


在这里插入图片描述


C语言风格比较

在这里插入图片描述


实列:

在这里插入图片描述

15.11.5 测试表达式符号

在[]和test中使用 在[[]] 和(())中使用 说明
-a && and ,与,两端都为真,则结果为真
-o || or,或,两端有一个为真,则结果为真
! ! not,非,两端相反,则结果为真

在这里插入图片描述


在这里插入图片描述

15.12 Shell分支if语句

15.12.1 单If语句

单If分支语句

if <条件表达式>
    then
 
        指令f
fi
if <条件表达式>;then

  指令f
fi

#简单记忆法:

如果 <你给我足够多的钱>
�
  那么

    我就给你干活
�
果如

#说明:<条件表达式> 可以是test、[]、[[]]、(())等条件表达式,每一个if条件语句都是以if开头,并带有then,最后以fi结尾

在这里插入图片描述

15.12.2 双If语句

if <条件表达式>
    then
 
        命令集1
 
    else
        命令集2f
fi
#简单记忆
�
如果 <你给我足够多的钱>
�
  那么
�
    我就给你干活
�
  否则
�
    我再考虑一下
�
果如

15.12.2 多If语句

if <条件表达式1>
    then
 
        指令集1
 
    elif <条件表达式2>
        then
 
            指令集2
 
    elif <条件表达式3>
        then
 
            指令集3     
 
    else
        指令集4f
fi

#提示:如果加elif,那么就要加then,每个elif都要带有then,最后结尾的else后面没有then

#简单记忆
如果 <你有房>
    那么
        我就嫁给你
    或者如果 <你家里有钱>
        那么
            我也可以嫁给你
    或者如果 <你很努力很吃苦>
        那么
          我们可以先谈谈男女朋友
    否则
        我们没戏
�
果如

15.13 Shell分支case语句

case "变量" in

    值1)
         指令1...
  如果变量的值等于1则执行指令1
          ;;
 
    值2)
         指令2...
 如果变量的值等于2则执行指令2
          ;;
    *) 
         指令3...
如果变量的值不等于以上的任何列值则执行认指令
esac

#说明:当变量的值等于1时,那么就会相应的执行指令1的相关命令输出,值等于2时就执行指令2的命令,以此类推,如果都不符合的话,则执行*后面的指令,要注意内容的缩进距离

15.14 break语句

在这里插入图片描述

15.15 Shell-数组

15.15.1 赋值数组

1.数组的定义
方法一: 用小括号将变量括起来赋值给数组变量,每个变量之间要用空格分隔

在这里插入图片描述


方法二: 用小括号将变量值括起来,同时采用键值对的形式赋值

在这里插入图片描述


方法三: 通过分别定义数组变量的方法来定义

在这里插入图片描述


方法四: 动态地定义数组变量,并使用命令的输出结果作为数组的内容
ps:因为是系统命令,所以要使用转义符号 反斜杠

在这里插入图片描述


ps:如果下标存在,会被覆盖原来的值

15.15.2 查数组

${ARRAY_NAME[INDEX]} #引用数组中的元素,注意: 引用时,只给数组名,表示引用下标为0的元素

${#ARRAY_NAME[]} #数组中元素的个数
${#ARRAY_NAME[@]} #数组中元素的个数
${ARRAY_NAME[
]} #引用数组中的所有元素
${ARRAY_NAME[@]} #引用数组中的所有元素
${#ARRAY_NAME} #数组中下标为0的字符个数

15.15.3 替换数组

在这里插入图片描述

15.15.4 删除数组

因为数组本质上还是变量,因此可以通过"unset"数组[下标]清除相应的数组元素,如果不带下标,表示清除整个数组的所有数据

在这里插入图片描述

15.15.5 切割数组

在这里插入图片描述

15.15.5 数据分片

格式:
${ARRAY_NAME[@]:offset:number}

在这里插入图片描述

15.15.6 遍历数组

遍历数组:
创建一个数组 array=(A B C D 1 2 3 4)

普通for循环
1.标准的for循环

for(( i=0; i<${#array[@]}; i++ ))
do
  #${#array[@]} 获取数组长度用于循环
   echo ${array[i]}
done

在这里插入图片描述


不带索引for循环

for  ...in 循环(不带数组下标)
for  var in ${array[*]}
do
  echo  $var
done

在这里插入图片描述


while循环

i=0
while [ $i -lt ${#array[@]}]
#当变量(下标)小于数组长度时进入循环体
do
  echo ${ array[$i] }
  #按下标打印数组元素
  let i++
done

在这里插入图片描述

15.16 Shell正则表达式

shell 正则表达式

一、正则表达式的概念及特点:
  正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,
这个“规则字符串”用来表达对字符串的一种过滤逻辑。规定一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是正则表达式(Regular Expression)。给定一个正则表达式和另一个字符串,我们可以达到如下的目的:

  1. 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
  2. 可以通过正则表达式,从字符串中获取我们想要的特定部分。

正则表达式的特点:

  1. 灵活性、逻辑性和功能性非常的强;
  2. 可以迅速地用极简单的方式达到字符串的复杂控制。
  3. 对于刚接触的人来说,比较晦涩难懂。  
    由于正则表达式主要应用对象是文本,因此它在各种文本编辑器场合都有应用,小到著名编辑器EditPlus,大到Microsoft Word、Visual Studio等大型编辑器,都可以使用正则表达式来处理文本内容

重要的文本处理工具:
vim sed awk grep

由三部分组成

在这里插入图片描述


字符类

在这里插入图片描述


数量限定符

在这里插入图片描述


位置限定符

在这里插入图片描述

15.17 Shell-grep

作为linux中最为常用的三大文本(awk,sed,grep)处理工具之一,
掌握好其用法是很有必要的。
首先谈一下grep命令的常用格式为:grep [选项] ”模式“ [文件1] [文件2]
grep家族总共有三个:grep,egrep,fgrep。

常用项:
  -E :开启扩展(Extend)的正则表达式。
  -i :忽略大小写(ignore case)。
  -v :反过来(invert),只打印没有匹配的,而匹配的反而不打印。
  -n :显示行号
  -w :被匹配的文本只能是单词,不能是单词中的某一部分,如文本中有liker,但搜寻的只是like,就可以使用-w选项来避免匹配liker
  -c :显示总共有多少行被匹配到了,而不是显示被匹配到的内容,注意如果同时使用-cv选项是显示有多少行没有被匹配到。
  -o :只显示被模式匹配到的字符串。
  --color :将匹配到的内容以颜色高亮显示
  -A n:显示匹配到的字符串所在的行及其后n行,after
  -B n:显示匹配到的字符串所在的行及其前n行,before
  -C n:显示匹配到的字符串所在的行及其前后各n行,context

1、直接输入要匹配的字符串,这个可以用fgrep(fast grep)代替来提高查找速度.

grep -f 等价于 fgrep

在这里插入图片描述


在这里插入图片描述

2.扩展的(Extend)正则表达式(注意要使用扩展的正则表达式要加-E选项,或者直接使用egrep)

grep -E 等价于 egrep

实战1:

输出 abc.log文件中 含有从abcd.log文件中读取出的关键词的内容并高亮显示

在这里插入图片描述


实战2: 输出以"。"结尾的

在这里插入图片描述


实战3: 输出 包含"开启"或者"忽略"的字段

在这里插入图片描述

15.18 Shell-sed流编辑器

Linux sed 命令是利用脚本来处理文本文件

sed 可依照脚本的指令来处理、编辑文本文件
Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。

语法:

sed [-hnV][-e

参数说明:

-e

-f<script文件>或–file=<script文件> 以选项中指定的script文件来处理输入的文本文件

-h或–help 显示帮助。

-n或–quiet或–silent 仅显示script处理后的结果。

-V或–version 显示版本信息。

动作说明:

a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~

c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!

d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;

i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);

p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~

s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

15.18.1 Shell-sed流编辑器–///或!!!或###替换

可以使用 / / / 也可以使用 ! ! ! 也可以使用 # # #

在这里插入图片描述

15.18.2 Shell-sed流编辑器–将替换之后的内容写进文件

将替换之后的内容写入指定文件中 w file

在这里插入图片描述

15.18.3 Shell-sed流编辑器–正则匹配替换

正则匹配 匹配以Hello开头的将它替换成HHello

在这里插入图片描述

15.18.4 Shell-sed流编辑器–使用数字方式进行寻址

在这里插入图片描述

15.18.5 Shell-sed流编辑器–加d删除

在这里插入图片描述


在这里插入图片描述

15.19 Shell-awk

AWK命令结构

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

15.19.1 Shell-awk-直接命令行调用

Shell脚本中awk指令的用法:

语法格式:awk [选项] ‘指令’ 操作文件
常用项:-F 指定分隔符,分隔符用""引起来

-v:var=value在awk程序开始之前指定一个值valu给变量var,这些变量值用于awk程序的BEGIN快
-f:后面跟一个保存了awk程序的文件,代替在命令行指定awk程序

实例1:在命令行直接输入awk指令:
1. awk ‘{print}’ awk.txt #逐行读取文件awk.txt内容并打印

在这里插入图片描述


2. awk ‘{print $0}’ awk.txt #逐行读取文件awk.txt内容并打印改行,$0保存的是当前行的内容

在这里插入图片描述


3. awk ‘{print “hello”}’ awk.txt #逐行读取awk.txt文件内容,每行结束后打印一个hello,
文件awk.txt有多少行就打印多少个hello

在这里插入图片描述


4.awk ‘{print $1}’ awk.txt #打印awk.txt的第一列内容,在不指定分割符的情况下,awk认使用空白做分割符

在这里插入图片描述


5.awk -F “:” ‘{print $1}’ /etc/passwd #以":"为分隔符打印/etc/passwd文件的第一例内容

15.19.2 Shell-awk-将awk指令写入文件,通过-f选项调用

将awk指令写入文件,通过-f选项调用
vim awkscript
BEGIN{
FS=":"
}
{print $1}
awk -f awkscript /etc/passwd

15.19.3 Shell-awk–begin和end

实例3:awk的BEGIN块和END块

BEGIN用于初始化FS变量(列分隔符),打印标题,或者初始化后需要在程序中调用全局变量
END用于执行最后的运算或者打印最终的输出结果
END块和BEGIN不是必须的

15.19.4 Shell-awk—在awk中使用正则匹配

实例4:在awk中使用正 则匹配,正则表达式必须要放在//中

  1. awk ‘/Hello/{print}’ awk.txt #打印awk.txt中匹配Hello的那一行内容

    在这里插入图片描述

  2. awk -F “:” ‘/123/{print $2}’ 1.txt
    #以":"为分隔符打印1.txt中匹配123的那一行中,第二列的内容

    在这里插入图片描述


    3.awk -F “:” ‘$1 ~ /root/{print $2}’ /etc/passwd
    #打印/etc/passwd中,第一列匹配root的行其第二列的内容 ~表示匹配

    在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐