第三部分 第1章 linux 与 shell 解析

1.1 linux 结构介绍

在认识一个新的东西时,先了解其结构对于我们了解它还是很有 帮助的。Linux 文件系统是呈树形结构,/ 为 Linux 的根目录,其下主要目录为 :

在这里插入图片描述

目录说明
/Linux 文件系统的入口,也是处于最高一级的目录,所有的目录、文件、设备都在/之下
/binbin 就是二进制(binary)英文缩写。在一般的系统当中,都可以在这个目录下找到 linux 常用的命令。系统所需要的那些命令位于此目录。
/boot内核和加载内核所需要的文件。一般情况下,GRUB 系统引导管理器也位于这个目录
/dev设备文件存储目录,比如终端、磁盘等
/etc所有的系统配置文件
/home普通用户家目录的默认存放目录
/lib库文件和内核模块所存放的目录
/media即插即用型存储设备的挂载点自动在这个目录下创建,比如 u盘、CDROM/DVD 自动挂载后,也会在这个目录中创建一个目录。
/mnt临时文件系统的挂载点目录
/opt第三方软件的存放目录
/rootLinux 超级权限用户 root 的家目录
/sbin基本的系统维护命令,只能由超级用户使用
/srv该目录存放一些服务启动之后需要提取的数据
/tmp临时文件目录
/usr存放用户使用系统命令和应用程序等信息,比如命令、帮助文件等。
/var存放经常变动的数据,比如日志、邮件、安装好的 php 环境等。

注意:以上几个加粗的目录需要了解。

1.2 linux 常用命令介绍

1.2.1 目录命令

(1)ls - 显示指定工作目录下之内容

语法: 
	ls [选项]

常用选项:
    -a 查看所有包括隐藏目录
    -l 长显示,显示目录或者目录详细信息包括大小 修改时间
    -d 显示目录
    -h 更加人性化显示 比如字节转换为MB,GB 不用自己算
    -i 查询目录inode号(inode存储目录的详细信息) 信息编号,类似于人的身份证号码

(2)mkdir - 创建目录

语法:
	mkdir [-p] dirName # -p 可选,确保目录名称存在,不存在的就建一个
    mkdir runoob # 在工作目录下,建立一个名为 runoob 的子目录

(3)pwd - 显示当前所在路径

语法:
    pwd [选项]

(4)cd - 切换当前工作目录

语法:
	cd [目标目录]
	
	cd ../ # 代表上一级
	cd / # 代表根目录

(5)cp - 复制目录

语法:
	cp [选项] 源目录 目标目录 # 可以复制多个,多个之间用 空格 隔开
	
常用选项:
	-r  若给出的源文件是一个目录文件,此时将复制该目录下所有的子目录和文件
    -p  除复制目录的内容外,还把修改时间和访问权限也复制到新目录中
    -rp 复制目录并且保留原目录属性

(6)mv - 剪切 / 重命名目录

语法:
	mv [选项] 源目录 目标目录
	
常用选项:	
	-b 当目标目录或目录存在时,在执行覆盖前,会为其创建一个备份
	-i 源目录和目标目录同名提示,输入 y 表示直接覆盖,输入 n 表示取消该操作
	-f 不询问强制覆盖

注意:如果需要实现改名,则在确定的目录后面加入修改后的名称。

(7)rm - 删除

语法:
	rm [选项] 目录名 # 可以删除多个
	
常用选项:
    -f 强制删除,不询问
    -r 将目录及以下之档案亦逐一删除
    -rf 一起使用则会将目录及以下文档都删除
1.2.2 文件命令

1. 基本命令

(1)touch - 创建文件

语法:
	touch 文件名

(2)cat - 显示文件内容

语法:
	cat [选项] 文件名
	
常用选项:
	-n--number1 开始对所有输出的行数编号
	-A, --show-all 显示所有隐藏字符

注意:tac 可以倒序查看,但不支持以上命令。

(3)more - 分页显示

语法:
	more  文件名
	
	按 空格键 下一页显示;
    按 b 键 上一页显示;
    按  h 键 使用中的说明文件;
    另搜寻字串的功能(与 vi 相似)。

​ 文件的复制,移动,删除 同 目录操作。

2. 搜索命令

(1)find - 查找文件

语法:
	find [范围] [-选项] 关键字
	例:find *.html 范围不写默认为当前目录。如果不确定的可以使用 * 代替。
	
常用选项:
	-name 文件名称符合 name 的文件
[iname 不区分大小写搜索]

例:find /etc/ -name passwd 或者 find /etc/ -name *.conf 。

	-size 根据文件大小查找
	
	-a 两个条件同时满足
	-o 两个条件满足任意一个即可
	
例:find /etc -size +163840 -a -size -204800 查找大于 80m 小于 100m 的文件。

(2)locate - 文件资料库查找

语法:
	locate 文件名

注意:不是默认的,无法直接使用,需要通过 yum install mlocate 安装后才能使用。

(3)grep - 在文件内查询字符串或者关键字

语法:
	grep [选项] [指定字符串] [文件]
	
常用选项:
	-i 不区分大小写
	-v 排除指定字符串
	-d 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作
	
	例:grep name *.html 在当前目录中,查找后缀为 html 文件中包含 name 字符串的文件并打印。

3. 文件编辑

所有的 Unix 系统都会内建 vi 文书编辑器,vim 不一定会存在。vim 是从 vi 发展出来的一个文本编辑器,相当于是 vi 的升级版。其区别主要体现在 :

1.对 vi 的完全兼容
	根据设定可以和原始 vi 完全兼容。
2.多次撤销
	例如 vi 里按 u 只能撤消上次命令,在 vim 里可以无限制的撤消。
3.远程文件编辑
	vim 可以运行于 x window、 mac os、 windows。
4.语法加亮
	vim 可以用不同的颜色来加亮你的代码。
......

(1)vi/vim 命令

# 操作类似,以下以 vi 演示,如果需要使用 vim 需要先安装
语法:
	vi 文件
	
基本上 vi/vim 共分为三种模式:命令模式,输入模式 和 底线命令模式。
    输入模式:
用户启动 vi/vim,便进入了命令模式。在这个模式下并非直接可以输入字符,而是执行了一个命令,常用命令	为:
i	在当前字符的左边插入
a	在当前字符的右边插入
o	在当前行下面插入一个新行

dd 	删除整行
ndd n 为数字,删除光标所在向下 n 行。
yy 	复制光标所在行
nyy n 为数字,复制光标所在向下 n 行
P 	小 p 将复制的数据在光标下一行粘贴,大 P 将复制的数据在光标上一行粘贴
u 	撤消前一个操作

    输入模式:
在命令模式下通过命令可以插入字符时则可以进入到输入模式,此时在终端最下面显示的是 --INSERT-- 。在该模式下就可以对文件的内容进行编辑。

    底线命令模式:
    	编辑完成后按 ESC 切换到底线模式。进入到底线模式后可以使用下面的命令来执行对应操作:
:w 	保存数据[强制操作使用 :w!]
:wq 保存退出
:q	不保存退出[强制操作使用 :q!]
:w 	文件名 相当于另存为
:set nu显示行号
:set nonu	取消行号
1.2.3 「用户」和 「组」 管理

Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统。对于用户账号主要有添加、修改 与 删除 等操作。

1. 用户管理

(1)useradd - 添加用户

语法:
	useradd [选项] 用户名
常用选项:
	-d 目录 指定用户主目录
	-m 联合 -d 当不存在时可以创建主目录
	-g 指定用户所属的用户组
	-s 指定用户的登录Shell
    例:useradd –d  /home/sam -m sam

(2)passwd - 添加密码

语法:
	passwd [选项] 用户名
常用选项:
	-d 删除用户密码

(3) 设置密码

# passwd user
更改用户 user 的密码 。
新的 密码: # 这里不会显示
重新输入新的 密码: # 这里不会显示
passwd:所有的身份验证令牌已经成功更新。
# 注意 设置密码不能过于简单

在创建了用户后,重新登录时通过新创建的用户名称和密码登录即可。

(4)usermod - 修改

语法:
	usermod [选项] 用户名
选项可以参考添加,修改用户账号就是根据实际情况更改用户的有关属性,主目录、用户组、登录Shell等。

(5)userdel - 删除账号

语法:
	userdel 选项 用户名
常用选项:
	-r 把用户的主目录一起删除

2. 组管理

每个用户都有一个用户组,而不同的用户可以有相同的用户组也可以有不同的用户组 :

在这里插入图片描述

对于组的操作主要也是添加、修改与删除等操作。

(1)groupadd - 添加

语法:
	groupadd [选项] 用户组

常用选项:
	-g GID 指定新用户组的组标识号(GID)。 例:groupadd -g 101 group1
	-o 一般与-g选项同时使用,表示新用户组的GID可以与系统已有用户组的GID相同

(2)groupmod - 修改

语法:
	groupmod [选项] 用户组

常用选项:
	-n 将用户组的名字改为新名字
	-g-o 与上相同
	
	例:groupmod -og 100 -n user group1 

(3)groupdel - 删除

语法:
	groupdel 用户组

如果一个用户有多个组,可以通过 newgrp 组名来切换。

1.2.4 权限设置

1. 常用的权限操作

权限设置 即控制用户对文件的权限的管理。权限 主要分为 读=》r写=》w执行=》x 权限。而 Linux 的文件 调用权限 分为三级 : 文件所有者(Owner=》o)、用户组(Group=》g)、其它用户(Other Users=》o)【如果要给所有用户添加可以使用 a 即 all】。

在 Linux 中想要修改权限可以使用 chmod 命令,而修改文件权限可以使用两种方式来实现,分别是: 符号模式八进制数字模式

(1)符号模式 - 即 通过符号修改用户的权限

例如:添加权限使用 +

语法:
	chmod 修改对象 操作 权限 文件/目录
	
修改对象:
	u(user)文件所有者
	g(group)	文件所有者所在组
	o(others)	所有其他用户
	a(all)所用用户, 相当于 ugo

操作:
	+	为指定的用户类型增加权限
	-	为指定用户类型去除权限
	=	设置指定用户权限的设置,即将用户类型的所有权限重新设置
	
    例:chmod g+w hello # 用户组添加写权限

(2)八进制模式 - 即使用八进制数来指定权限。

语法:
	chmod 八进制数 文件/目录
	
八进制数:
	基础:
01	执行
24	读
	组合:
3	写 + 执行
5	读 + 执行
6	读 + 写
7	读 + 写 + 执行
	
	例:
chmod 777 hello # 给所有用户添加 读写执行 权限
chmod 755 hello # 给所有者 读写执行 权限,所属组和其他 读 与 执行 权限

注意:只有文件 所有者超级用户 可以修改文件或目录的权限。如果需要对目录递归操作则可以加上 -R 参数来实现。

(3)chown - 改变所有者

语法:
	chown 用户 文件/目录
	例:chown user hello # 改变 hello 的所有者为 user

(4)chgrp - 改变所属组

语法:
	chgrp 组名 文件/目录
    例:chown group1 hello # 改变 hello 的所属组为 group1
1.2.5 进程管理

1. 常用进程操作

(1)ps - 进程查看

进程是正在执行的一个程序或命令,每一个进程都是一个运行的实体,都有自己的地址空间,并占用一定的系统资源。在 Linux 中查看进程可以使用 ps 命令。

语法:
	ps [选项] 
	
常用选项:
	-A 列出所有的进程 【-e 与之相同】
    -w 显示加宽可以显示较多的资讯
    -f显示UID,PPIP,C与STIME栏位
    -au 	显示较详细的资讯
    -aux 	显示所有包含其他使用者的行程	

(2)top - 实时显示进程动态

语法:
	top [选项]
	
常用选项:
	-c 	切换显示模式,只显示执行档的名称/显示完整的路径与名称
	-d	改变显示的更新速度【秒】

	在使用了 top 命令进入到交互模式之后,可以使用以下命令来修改查看:
P	以CPU使用率排序,默认就是此项
M	以内存的使用率排序
N	以PID排序
q	退出top

(3)kill - 杀死进程

语法:
	kill [选项] [进程号]
	
常用选项:
	-l 查看可用的进程信号
其中:
	1 	重新加载进程
	9 	杀死一个进程
	15 	正常停止一个进程
	
	例:
kill -9 666666 # 彻底杀死 id 为 666666 的进程

注意:与之类似的还有 killall 和 pkill 命令:killall 与 pkill 会杀死指定名字的所有进程。

2. 进程管理

如果你发现运行的一个程序需要很长的时间,但是还需要干其他的事情,你可以把当前的程序放到后台执行。命令放入后台可以使用以下几种方式:

  • command & :后台运行,你关掉终端会停止运行。
  • nohup command & :后台运行,你关掉终端也会继续运行。
  • Ctrl+Z 快捷键:命令执行过程中使用,使命令在后台暂停。

(1)&

例 - 查找文件并放入后台 :

find / -name hello&
[1] 92996
# 在 ‘find / -name hello’ 命令后面加上 & ,可以让命令在后台执行。其中 ‘ [1] ’ 是工作号,‘ 92996 ’ 是进程号。

(2)ctrl+z

例 - 实时显示进程动态,暂停放入后台 :

top # 回车执行,会实时显示
# 按 ctrl + z 显示以下内容
[1]+  已停止 top
# top命令被放入后台,其中 '[1]' 是工作号, '+' 代表是最近放入后台。

(3)jobs

例 - 通过 jobs 命令可以查看当前运行的任务 :

jobs
# 结果......
[1]   完成  find / -name hello
[2]-  已停止       top

(4)fg

例 - 调度到前台

fg 2
# 结果,上面的任务会继续执行

(5)bg

例 - 继续执行

bg 3
# 结果,在后台暂停的命令,变成继续执行

注意:在后台运行的任务无法使用标准输入,也就是无法输入任何指令,相关信息则依然会显示。

使用 ctrl+c 则可以终止并退出前台命令的执行,回到 shell。

3. 守护进程

守护进程即 一直在后台运行的进程。在我们执行一个 shell 脚本时,多数都存在一个父进程 终端 shell,而一旦父进程退出则会发送 SIGHUP 给所有子进程,子进程收到信号也会退出。如果我们要在退出 shell 的时候继续运行进程,则需要使用 nohup 忽略 SIGHUP 信号,或者 setsid 将父进程设为 init 进程(进程号为 1 )。

(1)nohup

在系统后台不挂断地运行命令,退出终端不会影响程序的运行

语法:
	nohup 命令 [&]
	
	例:
nohup /root/runoob.sh & # 在后台执行 runoob.sh 脚本 
# 出现: nohup: 忽略输入并把输出追加到"nohup.out"     则表示成功
# 也可以使用以下方式实现:
 1.nohup /root/runoob.sh &
 2.(/root/runoob.sh &
1.2.6 定时任务

(1)crontab - 定时任务

语法:
	crontab [选项]

常用选项:
	-e	编辑该用户的计时器设置
    -l	列出该用户的计时器设置
    -r	删除该用户的计时器设置

(2)定时任务的编写

语法: # 注意:这是一个格式而不是命令
	* * * * * 任务

	以上命令存在 5 个 * ,从左到右分别代表 几分、几时、几日、几月、周几【注意:最后面不是 年 而是 周几】。
	例:
* * * * * echo hello >>/test/hello.log # 每分钟向 /test/hello.log 文件中追加 hello

	# 注意:一个 * 并不代表只有一个时间,例如每天的 0时 与 12时 执行任务:
0 0,12 * * * 任务  

总结:
	不同单位时间用 「空格」 区分;
	相同单位时间用「,」(多个时间点 - xx时间 和 xx时间 执行)
	  或 「-」(时间范围 - xx时间 到 xx时间 执行)
	  或 「/」(频率 - 每过多长时间执行)。

注意:当定时任务过多时,建议使用 shell 脚本。

1.2.7 管道

管道 是一种通信机制,通常用于进程间的通信(也可通过 socket 进行网络通信),它表现出来的形式将前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin);即 前者的输出是后者的输入。管道命令使用|作为界定符号。

在这里插入图片描述

语法:
	命令|命令...... # 可以使用多个
	
	例如:
ps -ef|grep nginx # 找出进程中 nginx 相关的

注意:管道只能用于 具有亲缘关系 的进程间通信,即 前后命令不能毫无关系。更多更好的使用方式。

1.2.8 软件包管理

1. 压缩与解压

打包是指将一大堆文件或目录变成一个总的文件,压缩则是将一个大的文件通过一些压缩算法变成一个小文件。文件压缩后可以节约空间和方便网络传输。

(1)tar - 打包备份

在 Linux 系统里,tar 是将多个文件打包在一起,并且可以实现解压打包的文件的命令。是系统管理员最常用的命令之一, tar 命令不但可以实现对多个文件进行打包,还可以对多个文件打包后进行压缩。

语法:
	tar [选项] 后文件名 原文件/目录
	
常用选项:
	-c	打包
	-v	显示详细信息
	-f	指定文件名
	-z	压缩或解压
	-x	解包
	
	例:
tar -zcf test.tar.gz test # 打包并压缩 test 目录为 test.tar.gz。注意:后缀为 .tar.gz ; 当打包压缩完毕后,源文件还会存在
tar -zxf test.tar.gz # 解压缩 test.tar.gz 文件,同样 源文件还在

(2)gzip - 压缩与解压文件

gzip 也能实现文件的压缩,但是只能压缩文件而不能压缩目录,并且会删除源文件。如果想要使用 gzip 压缩目录,需要先使用 tar 命令打包目录。

语法:
	gzip [选项] 文件
	
	例:
tar -cf test.tar dir # 打包 test 目录
gzip dir.tar# 压缩 dir.tar  文件

# 注意:如果需要解压可以使用 -d 选项或者使用 gunzip 命令。

(3)zip - 打包压缩

zip 压缩格式是 Window 与 Linux 等多平台通用的压缩格式。与 gzip 相比,zip 可以压缩目录并且不会删除源文件。

语法:
	zip [选项] zip文件 源文件/目录

常用选项:
	-r	递归处理,将指定目录下的所有文件和子目录一并处理
	-x	压缩时排除符合条件的文件
	-q 	不显示指令执行过程
	
	例:
zip -r test.zip test # 压缩 test 目录为 test.zip 文件

# 注意:与 gzip 类似,如果需要解压,可以使用 unzip 命令解压。

2. 软件安装

在 Linux 中安装软件主要有以下几种方式 :

  • 源码包管理:Linux 的绝大多数开源软件都是直接以原码形式发布的,一般会被把源码打包成 .tar.gz 的归档压缩文件。我们使用这些软件前 需要将源代码编译成为二进制形式之后才能够运行使用

  • RPM 包管理:RMP 是 LINUX 下的一种软件的可执行程序,你只要安装它就可以使用了。这种软件安装包通常是一个 RPM 包,后缀是 .rpm,通过这种方式可以轻松实现软件的安装。

  • YUM 管理:RMP 软件包形式的管理虽然方便,但是需要手动解决软件包的依赖关系。YUM 是 RPM 的前端程序,其设计的目的是用来自动解决 rpm 包之间 的依赖关系

(1)YUM使用

利用 yum 可以帮我们进行 查询、安装、升级 与 删除的功能。

语法:
	yum [选项] [操作] 包
	
常用选项:
	-y	安装过程中的选项全部为 yes
	-q	不显示安装过程

常用操作:
	查询:
    	list	查询所有可用软件包列表
    	search	关键字	   搜索和关键字相关的包
	安装:
install 安装
	升级:
update	升级
	卸载:
remove	卸载

接下来对于 yum 的几种操作尝试看看。

(2)查询

    如果想要查询利用 yum 来查询原版 distribution 所提供的软件,或已知某软件的名称可以利用 查询 相关的参数来查找。
    
例:
	yum list # 会列出 yum 服务器上提供的所有软件名称
	
	# 列出 nginx 相关软件,最后的 installed 代表该软件已经安装
	[root@VM-0-13-centos yum.repos.d]# yum list|grep nginx
    bt-nginx118.x86_64                          1.18.0-1.el7               installed
	
	# 查看所有已经安装的软件 注意是 ed
	[root@VM-0-13-centos yum.repos.d]# yum list installed
	
	# 查看所有可以更新的软件  注意 有 s
	[root@VM-0-13-centos yum.repos.d]# yum list updates
	
	# 搜寻 nginx 相关软件
	[root@VM-0-13-centos yum.repos.d]# yum search nginx  

(3)安装

yum 安装软件需要使用 install 参数来实现安装。例:
	yum install pam-devel  # 安装  pam-devel,如果有相关软件需要安装或升级 yum 会自动帮你处理
	# 可以使用以下命令在后续操作中全选择 yes
	yum -y install pam-devel 

更新、删除 与 安装 类似,把 install 替换成 update 即可。

1.3 linux 下构建 lnmp 环境

1.3.1 Nginx 安装

1 . 安装先决条件

sudo yum install yum-utils

如果已经存在,请忽略

2 . 创建 yum 库

vi /etc/yum.repos.d/nginx.repo

在其中添加以下内容:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

为了避免干扰可以先备份一下其他的库并删除。

3 . 安装 nginx

sudo yum install nginx

以上 nginx 安装成功,通过 nginx -v 可以查看 nginx 版本。

4 . 页面访问

如果需要通过浏览器访问到 nginx 的首页,需要 :

  1. 开启 web 端口:firewall-cmd --permanent --add-port=80/tcp
  2. 重启 firewall:firewall-cmd --reload

再通过 ip 地址即可访问到。

5 . php 支持

以上各个软件都已经安装完毕,但是当你通过服务器访问 php 文件时,则会提示 File not found 。这里需要我们修改一下 nginx 的配置文件 - nginx.conf :

location ~ \.php$ {
 root   /usr/share/nginx/html;
 fastcgi_pass   127.0.0.1:9000;
 fastcgi_index  index.php;
 fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
 include/etc/nginx/fastcgi_params;
}

可以在安装完 php 后再来测试。

1.3.2 MySQL 安装

1 . 下载 mysql 源安装包

wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm

如果知道源,也可以直接配置修改 源 配置文件。

2 . 安装 mysql 源

yum localinstall mysql57-community-release-el7-8.noarch.rpm

安装完成后可以在 /etc/yum.repos.d 目录中看到对应的 源 配置文件。查看该配置文件可以看到有几个源,其中 enabled=1 的即为允许使用的源。如果需要可以根据自己的需求修改配置文件。

3 . 安装 mysql

yum install mysql-community-server

安装完成后可以启动 mysql:

systemctl start mysqld

mysql 会帮我们生成初始密码,可以通过 以下命令查看 :

cat /var/log/mysqld.log | grep password

# A temporary password is generated for root@localhost: wM))4aqnwqHf # 4aqnwqHf 即为密码

如果需要可以修改一下密码。如下 :

补充 - 密码修改 :

1 . 跳过验证

如果忘记密码而无法登录,可以在 my.cnf 配置文件中添加 skip-grant-tables 来跳过验证 :

vim /etc/my.cnf

---------------------------------------------------------------------

[mysql] 
# 在 mysql 的下面添加以下内容
skip-grant-tables

修改完成后要重启一下:service mysqld restart。

2 . 修改密码

输入 mysql -u root -p 然后直接敲回车,可以直接进入到 mysql :

# 选择 mysql 数据库
mysql> use mysql;

# 修改密码为 root ,authentication_string 是密码的字段
mysql> update user set authentication_string=password('root') where user='root';

修改完毕,去除 my.cnf 配置文件中添加的内容重新登录即可使用新增的密码登录。

1.3.3 PHP 安装

1 . 安装 epel-release 软件包

yum install epel-release

2 . 更新 rpm 源

rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

3 . 安装 php

在安装前,需要根据自己的需求使对应的源生效 :

vim /etc/yum.repos.d/remi-php70.repo

---------------------------------------------------------------------

[remi-php74]
name=Remi's PHP 7.4 RPM repository for Enterprise Linux 7 - $basearch
mirrorlist=http://cdn.remirepo.net/enterprise/7/php74/mirror
enabled=1

4 . 安装 php 相关软件包

yum --enablerepo=remi install php php-pdo php-mysql php-fpm php-cli php-common

以上 还可以根据自己的需求添加。安装完毕后可以通过 php -v 命令查看 php 版本。

1.4 shell 应用

1.4.1 Shell 简介

Shell 脚本(shell script)拆分为两部分为 shellscript。 操作系统的核心是需要保护起来的,所以我们需要一个桥梁来跟核心沟通,让核心帮助我们完成想要达到的工作,而 shell 则是这样一个桥梁。script 即为脚本的意思,根据编辑的内容来执行。shell script 即为给 shell 所写的「剧本」。

Shell 脚本命令的工作方式有两种:交互式和批处理。

1. 交互式(Interactive)

用户每输入一条命令就立即执行。

echo 'Hello World'

2. 批处理(Batch)

由用户事先编写好一个完整的 Shell 脚本,Shell 会一次性执行脚。

(1)编写脚本

[root@localhost shell]# vi hello.sh

#!/bin/bash
#first shell
echo 'Hello World'

没错,编写 shell 脚本只需要创建一个文件,并在该文件中编写预先设定的 linux 命令即可。该文件可以是任意后缀,只不过为了区分建议加上 .sh 作为后缀。

脚本说明 :

​ 第一行的(#!)是脚本声明,用来告诉系统使用哪种 Shell 解释器来执行该脚本。

​ 第二行(#)是注释信息,是对脚本功能和某些命令的介绍信息。

​ 第三行开始可以是自己的命令,例如平时执行的 linux 命令了 ls -l

(2)执行脚本

[root@localhost shell]# bash hello
Hello World
1.4.2 变量

1. 变量

是计算机内存的单元,其中存放的值可以改变。当 shell 脚本需要保存一些信息时,如一个文件名或是一个数字,就把它存放在一个变量中。

(1)变量命名

  • 变量名称可以由字母、数字和下划线组成 ,但是不能以数字开头,不能使用关键字(可用 help 命令查看保留关键字)。
  • 在 Bash 中,变量的默认类型都是字符串型。在赋值时等号两边不能存在空格,变量的值如果有空格,需要使用引号包括。
  • 定义变量时不需要添加 $ ,但是在使用时,需要使用 $ 或者使用反引号。
  • 环境变量名建议大写,便于区分。

(2)变量分类

  • 局部变量:局部变量定义在脚本或命令中,仅在当前 shell 实例中有效,其他 shell 程序不能访问该局部变量。
  • 环境变量:所有的程序都能访问环境变量,必要的时候 shell 脚本也可以定义环境变量。
  • shell 变量:shell 变量是由 shell 程序设置的特殊变量。shell 变量中既有环境变量也包含局部变量,这些变量保证了shell的正常运行。

(3)第一个变量

#!/bin/bash
#first shell
name="hello" # 定义值为 hello 的变量,名称为 name
echo $name # 输出变量的值

以上就定义完成了自己的变量,如果想要「过河拆桥」可以使用 unset 变量名称 的方式删除变量(unset name)。

2. 数据类型

(1)字符串

字符串是 shell 中最常用最有用的数据类型,字符串可以用单引号、双引号也可以不用引号。

# 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的。双引号则可以输出变量值。

#!/bin/bash
name="hello"
echo 'i am $name' # 输出 i am $name
echo "I am $name" # 输出 I am hello

在 shell 中,想要拼接字符串不需要添加额外符号。例如 :

#!/bin/bash
name="hello"
echo 'my name is '$name'. who are you?' # 输出 my name ishello. who are you?

(2) 整数型

在 Shell 中所有的变量默认都是字符串型。也就是说,如果不手动指定变量的类型,那么所有的数值都是不能进行运算的。例 :

#!/bin/bash
echo 1+1  # 结果输出为 1+1  如果想要进行运算则需要如下

如果想要进行数学运算,可以使用以下几种方式运算 :

运算指令作用
(())((a=1+2))
letlet b=6+13
exprexpr 2 + 8
$[]echo $[1+2]
bc可结合输入重定向使用

例 :

#!/bin/bash
echo $((1+1))

let a=1+1
echo $a

expr 1 + 1

echo $[1+1]

注意:expr 运算符左右需要有空格。

(3)数组

数组中可以存放多个值。bash 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小。数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。

创建数组有两种方式 :

#!/bin/bash
# 直接创建数组
array=(1,2,3,4,5,6)
echo $array

# 先创建数组,再通过下标赋值
array=()
array[0]=1
array[1]=2
echo $array

同样数组可以通过下标取值 :

echo ${array[1]}

echo ${array[@]}# 传递 @ 或者 * 都可以打印所有值。@ 是拆分的字符串,* 是一个字符串
1.4.3 运算符

shell 和其他编程语言一样,支持多种运算符。下面列出了一些常用运算符 :

优先级运算符说明
13-, +单目负、单目正
12!, ~逻辑非、按位取反或补码
11*,/, %乘、除、取模
10+, -加、减
9<< , >>按位左移、按位右移
8< =, > =, < , >小于或等于、大于或等于、小于、大于
7== , !=等于、不等于
6&按位与
5^按位异或
4|按位或
3&&逻辑与
2||逻辑或
1=,+=,*=,…赋值相关

以上优先级数字越大,优先级越高。与其他语言类似的是,可以通过括号提升优先级。

实例 :

#!/bin/bash
a=1
b=5

c=$(( $a+$b ))
echo $c

c=$(( $a*$b ))
echo $c

c=$(( $a/$b ))
echo $c

c=$(( ($a+$b)/$a ))
echo $c
1.4.4 字符串

1. 字符串截取

(1)cut

改命令可以显示每行从开头算起 num1 到 num2 的字符串。

语法:
	cut  [选项] [文件]
	
常用选项:
    -b 以字节为单位进行分割
    -d 自定义分隔符,默认为制表符
	-f 与-d一起使用,指定显示哪个区域
	
	例:
cut -b 6 hello.txt # 提取第六列字符
cut -b 2,6 hello.txt #  提取第二和六列字符
cut -d ':' -f 2 hello.txt  # 以 :为分隔符取第二列

(2)awk

文本分析工具。

awk 命令也叫 awk 编程,你没看错它就是一个编程语言,在这里我们主要介绍其使用方式。其特点为可以识别非制表符的空格,用来解决 cut 命令解决不了的提取列工作。

语法:
	awk '条件1{动作1}条件2{动作2}...' 文件名
	
	awk 后面需要接一对引号,并且在其中需要加上 {}
	例:
ps -aux|awk '{print $2 "\t" $11}' # 查看进程的 PID 和 COMMAND 并以 [tab] 隔开
ps -aux|awk '0<1 {print $2 "\t" $11}' # 前面加入条件则会在条件成立后执行

补充:printf 是另一个输出命令不会自动换行,print 可以自动换行,但是只有 awk 中可以使用。

(3)sed

利用脚本来处理文本文件。

语法:
	sed [选项] [动作] 文件名
	
常用选项:
	-n 仅显示script处理后的结果
	-e 以选项中指定的script来处理输入的文本文件
	-i 用sed的修改结果直接修改读取数据的文件,而不由屏幕输出	

常用动作:
    a 追加,a 的后面接字串,这些字串会在新的一行出现
    i 插入,i 的后面接字串,这些字串会在新的一行出现
    c 替换行,c 的后面接字串,这些字串可以替换原数据行,替换多行时末位使用 \ 表示未完结
    s 替换字符串,用一个字符串替换另外一个字符串
    p 打印,输出指定的行
    d 删除
    
    例:
sed -e 2a\newmessage hello.txt # 在 hello.txt 文件中添加 newmessage
cat hello.txt | sed -n '2,3p' # 只显示 第 2,3 行的内容
cat hello.txt | sed '1,2d' # 删除 hello.txt 文件中的 1,2 行显示

2. 字符处理

(1)sort - 排序

语法:
    sort [选项] 文件名
    
常用选项:
	-f 忽略大小写
	-n 依照数值的大小排序
	-r 反向排序
	-t 指定排序时所用的栏位分隔字符
	
	例:
sort hello.txt # 排序查看 hello.txt 中的内容
sort -r hello.txt # 反向排序

(2)wc - 计算字数

语法:
    wc [选项] 文件名
    
常用选项:
	-l 只统计行数
	-w 只统计单词数
	-m 只统计字符数
	
	例:
wc hello.txt # 结果 行数,单词 以及 字符数  都会显示
wc -l hello.txt # 统计 行数
1.4.5 条件判断

1. 检测

Shell 中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的检测。

语法:
    test 表达式

2. 数值判断

参数说明
-eq等于则为真
-ne不等于则为真
-gt大于则为真
-ge大于等于则为真
-lt小于则为真
-le小于等于则为真

例 :

[ 1 -le 2 ] && echo 'yes' || echo 'no' # 1是否小于2 小则为真
test 1 -le 2  && echo 'yes' || echo 'no' # 1是否小于2 小则为真
# 注意:中括号两边包含空格

以上两种方式可以得到结果,通过 echo 的方式来帮助我们查看结果,下面以第一种方式为主演示。

3. 字符串判断

参数说明
=等于则为真
!=不相等则为真
-z 字符串字符串的长度为零则为真
-n 字符串字符串的长度不为零则为真

例 :

name=hello
[ $name = 'hello' ] && echo 'yes' || echo 'no' # 判断变量是否为 hello
[ -z $name ] && echo 'yes' || echo 'no' # 判断字符串长度是否为 0

4. 文件判断

参数说明
-e 文件名如果文件存在则为真
-r 文件名如果文件存在且可读则为真
-w 文件名如果文件存在且可写则为真
-x 文件名如果文件存在且可执行则为真
-s 文件名如果文件存在且至少有一个字符则为真
-d 文件名如果文件存在且为目录则为真
-f 文件名如果文件存在且为普通文件则为真
-c 文件名如果文件存在且为字符型特殊文件则为真
-b 文件名如果文件存在且为块特殊文件则为真

例 :

[ -e ./hello.txt ] && echo 'yes' || echo 'no' # 判断当前目录下是否存在 hello.txt 文件
[ -r ./hello.txt ] && echo 'yes' || echo 'no' # 判断当前目录下是否存在 hello.txt 文件并且是否可读
1.4.6 流程控制

if … elseif

语法:
	1.
if [ 条件判断 ];then
    成立的工作内容
fi
	2.
if [ 条件判断1 ];then
    1成立的工作内容
elif [ 条件判断2 ] ;then
    2成立的工作内容
else
    都不成立的工作内容
fi
	
	例:
a=1
b=2
if [ $a == $b ];then
	echo 'a和b相等';
fi
# 判断 a 和 b 是否相等,相等则输出

if [ $a == 1 ];then
    echo 'a = 1'
elif [ $a == 2 ] ;then
    echo 'a = 2'
else
    echo '都不成立'
fi
# 判断 a 的值,并输出对应内容

case … esac

类似于 switch … case :

语法:
    casein
模式1)
	程序段
	;;
模式2)
	程序段
	;;
*)
	程序段
	;;
    esac
	
	例:
a=2
case $a in
    1)
echo '值是1';
;;
    2echo '值是2';
;;
    *)
echo '未知值';
;;
esac

for … do … done

语法:
    1.
for var in item1 item2 ... 
do
    程序段
done
	2.
	    for (( 初始值;循环控制调节;变量变化 ))
do
    程序段
done

	例:
    	for a in 1 2 3 4 5 6
do
    echo '我在:'$a
done
# 上面代码会将 in 后面的值依次给 a 使用

for (( i=0;i<6;i++ ))
do
    echo 'i是'.$i
done
# 上述代码会根据条件重复执行 do 后面的代码

while 与 until

语法:
    1.条件判断式成立则循环
while [ 条件判断式 ] 
do 
    程序段 
done 
	2.条件判断式不成立则循环
	    until [ 条件判断式 ] 
do 
    程序段 
done 

	例:
i=1 
while [ $i -le 6 ] 
do 
    i=$(( $i+1 )) 
done 
echo 'i的值是:'$i
	    # 如果变量 i 的值小于等于 100

until  [ $i -gt 6 ] 
do 
    i=$(( $i+1 )) 
done 
echo 'i的值是:'$i
# 如果 i 的值大于 6 则停止

输出重定向 ???

1.4.7 函数

1. 函数定义

shell 可以用户定义函数,在 shell 脚本中可以调用。shell 中函数的定义格式如下 :

语法:
    [ function ] funname [()]
    {
程序段
    }

	例:
 first(){
    echo '第一个函数'
}
first # 函数的调用

2. 函数参数

在调用函数的时候,同样可以给函数传递参数使用 :

first(){
	echo "第一个参数: $1"
    echo "第二个参数: $2"
    echo "第三个参数: $3"
    echo "第十个参数: ${10}"
    echo "参数总数有 $# 个"
    echo "作为一个字符串输出所有参数 $*"
}
first 1 2 3 4 5 6 7 8 9 10 11 12

说明 :

参数说明
$#传递到脚本或函数的参数个数
$*以一个单字符串显示所有向脚本传递的参数
$$脚本运行的当前进程ID号
$!后台运行的最后一个进程的ID号
$@与$*相同,但是使用时加引号,并在引号中返回每个参数。
$-显示Shell使用的当前选项,与set命令功能相同。
$?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

3. 传递参数

我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$nn 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数…,如下 :

例:
first(){
	echo "第一个参数: $1" # 1
    echo "第二个参数: $2" # 2
    echo "第三个参数: $3" # 3
    echo "参数总数有 $# 个" # 3
}
first $1 $2 $3

在运行脚本时需要传递参数 :

bash hello.sh 1 2 3

注意:并不是一定要传递给函数,只要定义了 $1,$2,… 等,就可以在执行脚本时传递参数使用。

4. 补充:输入输出重定向

我们在执行一个指令的时候,这个指令会经过处理将数据输出到屏幕上, 该数据可能是 标准输出[正确执行的结果] 和 标准错误输出[执行时产生的错误信息]。如果所有信息都输出到屏幕则会显得杂乱,我们可以通过重定向的功能分别写入其他文件中去。在使用该功能时,需要使用以下字符 :

字符说明
指令 > 文件将输出重定向到文件
指令 < 文件将输入重定向到文件
指令 >> 文件将输出以追加的方式重定向到文件

例 :

# 输出重定向:改变数据从程序流向哪里。
echo '原神' > yuanshen.txt # 把 '原神' 写入到 yuanshen.txt 文件中,也可以是通过指令查询到的内容写入 如  who > users
echo 'www.yuanshen.com' >> yuanshen.txt # 追加网址到文件,注意是 >> 如果是 > 则会直接覆盖

# 输入重定向:改变数据从哪里流向程序。
wc -l < yuanshen.txt # 等价于 cat yuanshen.txt | wc -l
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纳西妲爱编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值