第三部分 第1章 linux 与 shell 解析
1.1 linux 结构介绍
在认识一个新的东西时,先了解其结构对于我们了解它还是很有 帮助的。Linux 文件系统是呈树形结构,/ 为 Linux 的根目录,其下主要目录为 :
注意:以上几个加粗的目录需要了解。
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 或 --number 由 1 开始对所有输出的行数编号 -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 八进制数 文件/目录 八进制数: 基础: 0 无 1 执行 2 写 4 读 组合: 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 的首页,需要 : 开启 web 端口:firewall-cmd --permanent --add-port=80/tcp
重启 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)拆分为两部分为 shell 和 script。 操作系统的核心是需要保护起来的,所以我们需要一个桥梁来跟核心沟通,让核心帮助我们完成想要达到的工作,而 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 如果想要进行运算则需要如下 如果想要进行数学运算,可以使用以下几种方式运算 :
例 : #!/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 和其他编程语言一样,支持多种运算符。下面列出了一些常用运算符 :
以上优先级数字越大,优先级越高。与其他语言类似的是,可以通过括号提升优先级。 实例 : #!/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. 数值判断
例 : [ 1 -le 2 ] && echo 'yes' || echo 'no' # 1是否小于2 小则为真 test 1 -le 2 && echo 'yes' || echo 'no' # 1是否小于2 小则为真 # 注意:中括号两边包含空格 以上两种方式可以得到结果,通过 echo 的方式来帮助我们查看结果,下面以第一种方式为主演示。
3. 字符串判断
例 : name=hello [ $name = 'hello' ] && echo 'yes' || echo 'no' # 判断变量是否为 hello [ -z $name ] && echo 'yes' || echo 'no' # 判断字符串长度是否为 0
4. 文件判断
例 : [ -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 : 语法: case 值 in 模式1) 程序段 ;; 模式2) 程序段 ;; *) 程序段 ;; esac 例: a=2 case $a in 1) echo '值是1'; ;; 2) echo '值是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 说明 :
3. 传递参数
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:
$n
。
n
代表一个数字,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