Linux学习笔记

学习时间:2022年9月29日

学习来源:Linux就该这么学第二版

1 简介

1.1 开源许可

  • GNU通用公共许可证(General Public License,GPL):目前广泛使用的开源软件许可协议之一,用户享有运行、学习、共享和修改软件的自由。GPL的目的是保证程序员在开源社区中所做的工作对整个世界是有益的,所开发的软件也是自由的,并极力避免开源软件被私有化以及被无良软件公司所剥削。

    现在,只要软件中包含了遵循GPL许可证的产品或代码,该软件就必须开源、免费,因此这个许可证并不适合商业收费软件。遵循该许可证的开源软件数量极其庞大,包括Linux内核在内的大多数的开源软件都是基于GPL许可证的。

  • 较宽松通用公共许可证(Lesser GPL, LGPL):一个主要为保护类库权益而设计的GPL开源协议。与标准GPL许可证相比,LGPL允许商业软件以类库引用的方式使用开源代码,而不用将其产品整体开源,因此普遍被商业软件用来引用类库代码。

  • 伯克利软件发布版(Berkeley Software Distribution, BSD)许可证:另一款被广泛使用的开源软件许可协议。相较于GPL许可证,BSD更加宽松,适合于商业用途。用户可以使用、修改和重新发布遵循该许可证的软件,并且可以将软件作为商业软件发布和销售。

  • Apache许可证(Apache License):顾名思义,是由Apache软件基金会负责发布和维护的开源许可协议。作为当今世界上最大的开源基金会,Apache不仅因此协议而出名,还因市场占有率第一的Web服务器软件而享誉行业。目前使用最广泛的Apache许可证是2004年发行的2.0版本,它在为开发人员提供版权及专利许可的同时,还允许用户拥有修改代码及再发布的自由。该许可证非常适合用于商业软件,现在热门的Hadoop、Apache HTTP Server、MongoDB等项目都是基于该许可证研发的。

  • MIT许可证(Massachusetts Institute of Technology License):源于麻省理工学院,又称为X11协议。MIT许可证是目前限制最少的开源许可证之一,用户可以使用、复制、修改、再发布软件,而且只要在修改后的软件源代码中保留原作者的许可信息即可,因此普遍被商业软件(例如jQuery与Node.js)所使用。也就是说,MIT许可证宽松到一个新境界,即用户只要在代码中声明了MIT许可证和版权信息,就可以去做任何事情,而无须承担任何责任。

  • Mozilla公共许可证(Mozilla Public License,MPL):于1998年初由Netscape公司的Mozilla小组设计,原因是它们认为GPL和BSD许可证不能很好地解决开发人员对源代码的需求和收益之间的平衡关系,因此便将这两个协议进行融合,形成了MPL。

image-20220929142916796

1.2 常见的Linux系统

Linux系统内核指的是一个由Linus Torvalds负责维护,提供硬件抽象层、磁盘、文件系统控制及多任务功能的系统核心程序。

Linux发行套件系统是我们常说的Linux操作系统,也就是由Linux内核与各种常用软件的集合产品。

  • 红帽企业版系统(RHEL,RedHatEnterpriseLinux):最初于2002年3月面世。红帽企业版Linux当时是全世界使用最广泛的Linux系统之一,在世界500强企业中,所有的航空公司、电信服务提供商、商业银行、医疗保健公司均无一例外地通过该系统向外提供服务。

image-20220929144200752

  • CentOS社区企业操作系统(Community Enterprise Operating System):由开源社区研发和维护的一款企业级Linux操作系统,在2014年1月被红帽公司正式收购。从本质上来说,由于CentOS是针对红帽企业版Linux进行修改后再发布的版本,因此不会针对它单独开发新功能。

image-20220929144212291

  • Fedora Linux:Fedora Linux是正正经经的红帽公司自己的产品,最初是为了给红帽企业版Linux制作和测试第三方软件而构建的产品,孕育了最早的开源社群,固定每6个月发布一个新版本,当前在全球已经有几百万的用户。Fedora是桌面版本的Linux系统,也被称为RHEL系统的“试验田”。

image-20220929144219375

  • Debian Linux:Debian系统具有很强的稳定性和安全性,并且提供了免费的基础支持,可以良好地适应各种硬件架构,以及提供近十万种不同的开源软件,在国外拥有很高的认可度和使用率。虽然Debian也是基于Linux内核,但是在实际操作中还是跟红帽公司的产品有一些差别,例如RHEL 7和RHEL 8分别使用Yum和DNF工具来安装软件,而Debian使用的则是APT工具。

image-20220929144227232

  • Ubuntu Linux:ubuntu是一款桌面版Linux系统,以Debian为蓝本进行修改和衍生而来,发布周期为6个月。Ubuntu系统现在由Canonical公司提供商业技术支持,只要购买付费技术支持服务就能获得帮助,桌面版系统最长时间3年,服务器版系统最长时间5年。

image-20220929144234148

  • Kali Linux:这款系统一般是供黑客或安全人员使用的,能够以此为平台对网站进行渗透测试,通俗来讲就是能“攻击”网站。

image-20220929144242593

2 基础命令

2.1 shell和bash

image-20220929145041331

管理计算机硬件的其实是内核,用户正是通过shell来跟内核通信的,从本质上说shell是一个能执行各种命令的宏处理器。而bash(/bin/bash)就是linux默认的shell。

Shell就是终端程序的统称,它充当了人与内核(硬件)之间的翻译官,用户把一些命令“告诉”终端程序,它就会调用相应的程序服务去完成某些工作。现在包括红帽系统在内的许多主流Linux系统默认使用的终端是Bash(Bourne-Again SHell)解释器。

必须肯定的是,Linux系统中有些图形化工具(比如逻辑卷管理器[Logical Volume Manager,LVM])确实非常好用。但是,很多图形化工具其实只是调用了命令脚本来完成相应的工作,或往往只是为了完成某种特定工作而设计的,缺乏Linux命令原有的灵活性及可控性。再者,图形化工具相较于Linux命令行界面会更加消耗系统资源,因此经验丰富的运维人员甚至都不会给Linux系统安装图形界面,在需要开始运维工作时直接通过命令行模式远程连接过去。

2.2 命令格式

常见的执行Linux命令的格式是下面这样的:

命令名称 [命令参数] [命令对象]

参数可以用长格式(完整的选项名称),也可以用短格式(单个字母的缩写),两者分别用---作为前缀。

格式 示例
长格式 man --help
短格式 man -h

注意:命令名称、命令参数与命令对象之间要用空格进行分隔,且字母严格区分大小写。

注意:[root@linuxprobe~]这部分内容是终端提示符,它用于向用户展示一些基本的信息——当前登录用户名为root,简要的主机名是linuxprobe,所在目录是(这里的~是指用户家目录),#表示管理员身份(如果是$则表示普通用户,相应的权限也会小一些)。

2.3 常用系统工作命令

2.3.1 echo

echo命令用于在终端设备上输出字符串或变量提取后的值

语法格式为echo [字符串] [$变量]

示例

1
2
3
4
[root@VM-24-5-centos ~]# echo hello world
hello world
[root@VM-24-5-centos ~]# echo $SHELL
/bin/bash

2.3.2 date

date命令用于显示或设置系统的时间与日期

语法格式为date [+指定的格式]

示例

1
2
3
4
[root@VM-24-5-centos ~]# date
Thu Sep 29 15:45:13 CST 2022
[root@VM-24-5-centos ~]# date "+%Y-%m-%d %H:%M:%S"
2022-09-29 15:45:20

2.3.3 reboot

reboot命令用于重启系统,输入该命令后按回车键执行即可。

由于重启计算机这种操作会涉及硬件资源的管理权限,因此最好是以root管理员的身份来重启,普通用户在执行该命令时可能会被拒绝。

2.3.4 poweroff

poweroff命令用于关闭系统,输入该命令后按回车键执行即可。

与上面相同,该命令也会涉及硬件资源的管理权限,因此最好还是以root管理员的身份来关闭电脑。

2.3.5 wget

wget命令用于在终端命令行中下载网络文件,英文全称为“web get”

语法格式为wget [参数] 网址

参数 作用
-b 后台下载模式
-P 下载到指定目录
-t 最大尝试次数
-c 断点续传
-p 下载页面内所有资源,包括图片、视频等
-r 递归下载

示例

尝试使用wget命令从本书的配套站点中下载本书最新的PDF格式的电子文档:

image-20220929154830371

2.3.6 ps

ps命令用于查看系统中的进程状态,英文全称为“processes”

语法格式为ps [参数]

参数 作用
-a 显示所有进程(包括其他用户的进程)
-u 用户以及其他详细信息
-x 显示没有控制终端的进程

在Linux系统中有5种常见的进程状态,分别为运行、中断、不可中断、僵死与停止,其各自含义如下所示:

  • R(运行):进程正在运行或在运行队列中等待。
  • S(中断):进程处于休眠中,当某个条件形成后或者接收到信号时,则脱离该 状态。
  • D(不可中断):进程不响应系统异步信号,即便用kill命令也不能将其中断。
  • Z(僵死):进程已经终止,但进程描述符依然存在, 直到父进程调用wait4()系统函数后将进程释放。
  • T(停止):进程收到停止信号后停止运行。

除了上面5种常见的进程状态,还有可能是高优先级(<)、低优先级(N)、被锁进内存(L)、包含子进程(s)以及多线程(l)这5种补充形式。

示例

1
ps aux

image-20220929155217121

注意:在Linux系统中的命令参数有长短格式之分,长格式和长格式之间不能合并,长格式和短格式之间也不能合并,但短格式和短格式之间是可以合并的,合并后仅保留一个减号(-)即可。另外ps命令可允许参数不加减号(-),因此可直接写成ps aux的样子。

2.3.7 pstree

pstree命令用于以树状图的形式展示进程之间的关系,英文全称为“process tree”,输入该命令后按回车键执行即可。

示例

1
pstree

image-20220929155449224

2.3.8 top

top命令用于动态地监视进程活动及系统负载等信息,输入该命令后按回车键执行即可。

前面介绍的命令都是静态地查看系统状态,不能实时滚动最新数据,而top命令能够动态地查看系统状态。top是相当好用的性能分析工具。

示例

image-20220929161112813

top命令执行结果的前5行为系统整体的统计信息,其所代表的含义如下:

  • 第1行:系统时间、运行时间、登录终端数、系统负载(3个数值分别为1分钟、5分钟、15分钟内的平均值,数值越小意味着负载越低)。
  • 第2行:进程总数、运行中的进程数、睡眠中的进程数、停止的进程数、僵死的进程数。
  • 第3行:用户占用资源百分比、系统内核占用资源百分比、改变过优先级的进程资源百分比、空闲的资源百分比等。其中数据均为CPU数据并以百分比格式显示,例如“99.9 id”意味着有99.9%的CPU处理器资源处于空闲。
  • 第4行:物理内存总量、内存空闲量、内存使用量、作为内核缓存的内存量。
  • 第5行:虚拟内存总量、虚拟内存空闲量、虚拟内存使用量、已被提前加载的内存量。

2.3.9 nice

nice命令用于调整进程的优先级

语法格式为nice 优先级数字 服务名称

在top命令输出的结果中,PRNI值代表的是进程的优先级,数字越低(取值范围是-20~19),优先级越高。在日常的生产工作中,可以将一些不重要进程的优先级调低,让紧迫的服务更多地利用CPU和内存资源,以达到合理分配系统资源的目的。

示例

例如将bash服务的优先级调整到最高:

1
nice -n -20 bash

2.3.10 pidof

pidof命令用于查询某个指定服务进程的PID号码值

语法格式为pidof [参数] 服务名称

示例

1
2
[root@VM-24-5-centos ~]# pidof sshd
16003 8979 1355

2.3.11 kill

kill命令用于终止某个指定PID值的服务进程

语法格式为kill [参数] 进程的PID

但有时系统会提示进程无法被终止,此时可以加参数-9,表示最高级别地强制杀死进程。

示例

1
kill -9 16003

2.4 系统状态检测命令

2.4.1 ifconfig

ifconfig命令用于获取网卡配置与网络状态等信息,英文全称为“interface config”

语法格式为ifconfig [参数] [网络设备]

示例

image-20220929162548677

2.4.2 uptime

uptime命令用于查看系统的负载信息,输入该命令后按回车键执行即可。

它可以显示当前系统时间、系统已运行时间、启用终端数量以及平均负载值等信息。平均负载值指的是系统在最近1分钟、5分钟、15分钟内的压力情况。所以建议负载值保持在1左右,在生产环境中不要超过5就好。

示例

image-20220929162731366

2.4.3 free

free命令用于显示当前系统中内存的使用量信息

语法格式为free [-h]-h为易读模式,建议加上

示例

image-20220929163130112

2.4.4 last

last命令用于调取主机的被访记录,输入该命令后按回车键执行即可。

示例

image-20220929163544445

2.4.5 netstat

netstat命令用于显示如网络连接、路由表、接口状态等的网络相关信息,英文全称为“network status”

语法格式为netstat [参数]

参数 作用
-a 显示所有连接中的Socket
-p 显示正在使用的Socket信息
-t 显示TCP协议的连接状态
-u 显示UDP协议的连接状态
-n 使用IP地址,不使用域名
-l 仅列出正在监听的服务状态
-i 显示网卡列表信息
-r 显示路由表信息

示例

image-20220929163745636

2.4.6 history

history命令用于显示执行过的命令历史

语法格式为history [-c],可以使用-c参数清空所有的命令历史记录

示例

image-20220930160826959

历史命令会被保存到用户家目录中的.bash_history文件中。Linux系统中以点(.)开头的文件均代表隐藏文件,这些文件大多数为系统服务文件,可以用cat命令查看其文件内容:

1
cat ~/.bash_history

2.4.7 sosreport

sosreport命令用于收集系统配置及架构信息并输出诊断文档,输入该命令后按回车键执行即可。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[root@linuxprobe ~]# sosreport
sosreport (version 3.6)
This command will collect diagnostic and configuration information from
this Red Hat Enterprise Linux system and installed applications.

An archive containing the collected information will be generated in
/var/tmp/sos.9_i0glu8 and may be provided to a Red Hat support
representative.

Any information provided to Red Hat will be treated in accordance with
the published support policies at:
https://access.redhat.com/support/
The generated archive may contain data considered sensitive and its
content should be reviewed by the originating organization before being
passed to any third party.

No changes will be made to system configuration.
Press ENTER to continue, or CTRL-C to quit.
此处按下回车键进行确认
Please enter the case id that you are generating this report for []:此处按下回车键进行确认
Setting up archive ...
Setting up plugins ...
Running plugins. Please wait ...
………………省略部分输出信息………………
Finished running plugins
Creating compressed archive...

Your sosreport has been generated and saved in:
/var/tmp/sosreport-linuxprobe.com-2021-05-18-jnkaspu.tar.xz

The checksum is: 9fbecbd167b7e5836db1ff8f068c4db3
Please send this file to your support representative.

2.5 查找定位文件命令

2.5.1 pwd

pwd命令用于显示用户当前所处的工作目录,英文全称为“print working directory”,输入该命令后按回车键执行即可。

1
2
[root@VM-24-5-centos ~]# pwd
/root

2.5.2 cd

cd命令用于切换当前的工作路径,英文全称为“change directory”

语法格式为cd [参数] [目录]

1
2
3
[root@VM-24-5-centos ~]# cd /etc/
[root@VM-24-5-centos etc]# cd ..
[root@VM-24-5-centos /]#

2.5.3 ls

ls命令用于显示目录中的文件信息,英文全称为“list”

语法格式为ls [参数] [文件名称]

  • -a参数可以看到全部文件(包括隐藏文件)
  • -l参数可以查看文件的属性、大小等详细信息
  • -d:仅列出目录本身,而不是列出目录内的文件数据(常用)
  • 将这两个参数整合之后,再执行ls命令即可查看当前目录中的所有文件并输出这些文件的属性信息,注意-不能省略,只有ps命令才可以省略

示例

image-20220930161431186

2.5.4 find

find命令用于按照指定条件来查找文件所对应的位置

语法格式为find [查找范围] 寻找条件

本书中会多次提到“Linux系统中的一切都是文件”。在Linux系统中,搜索工作一般都是通过find命令来完成的,它可以使用不同的文件特性作为寻找条件(如文件名、大小、修改时间、权限等信息),一旦匹配成功则默认将信息显示到屏幕上。

参数 作用
-name 匹配名称
-perm 匹配权限(mode为完全匹配,-mode为包含即可)
-user 匹配所有者
-group 匹配所有组
-mtime -n +n 匹配修改内容的时间(-n指n天以内,+n指n天以前)
-atime -n +n 匹配访问文件的时间(-n指n天以内,+n指n天以前)
-ctime -n +n 匹配修改文件权限的时间(-n指n天以内,+n指n天以前)
-nouser 匹配无所有者的文件
-nogroup 匹配无所有组的文件
-newer f1 !f2 匹配比文件f1新但比f2旧的文件
-type b/d/c/p/l/f 匹配文件类型(后面的字幕字母依次表示块设备、目录、字符设备、管道、链接文件、文本文件)
-size 匹配文件的大小(+50KB为查找超过50KB的文件,而-50KB为查找小于50KB的文件)
-prune 忽略某个目录
-exec …… {}\; 后面可跟用于进一步处理搜索结果的命令

示例

根据文件系统层次标准(Filesystem Hierarchy Standard)协议,Linux系统中的配置文件会保存到/etc目录中。如果要想获取该目录中所有以host开头的文件列表,可以执行如下命令:

1
find /etc -name "host*"

image-20220930162454494

2.6 文本文件编辑命令

2.6.1 cat

cat命令用于查看纯文本文件(内容较少的),英文全称为“concatenate”

语法格式为cat [参数] 文件名称-n用于显示行号

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@linuxprobe ~]# cat -n initial-setup-ks.cfg 
1 #version=RHEL8
2 # X Window System configuration information
3 xconfig --startxonboot
4 # License agreement
5 eula --agreed
6 # Use graphical install
7 graphical
8 # Network information
9 network --bootproto=dhcp --device=ens160 --onboot=off --ipv6=auto --no-activate
10 network --bootproto=dhcp --hostname=localhost.localdomain
11 repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream
12 ignoredisk --only-use=sda
13 # Use CDROM installation media
14 cdrom
15 # Run the Setup Agent on first boot
16 firstboot --enable
17 # System services
………………省略部分输出信息………………

2.6.2 more

more命令用于查看纯文本文件(内容较多的)

语法格式为more [参数] 文件名称,使用空格键或回车键向下翻页

2.6.3 head

head命令用于查看纯文本文件的前N

语法格式为head [参数] 文件名称-n跟上数字显示多少行

示例

1
head -n 10 a.txt

2.6.4 tail

tail命令用于查看纯文本文件的后N行或持续刷新文件的最新内容

语法格式为tail [参数] 文件名称

示例

1
tail -n 10 a.txt

tail命令最强悍的功能是能够持续刷新一个文件的内容,当想要实时查看最新的日志文件时,这特别有用,此时的命令格式为tail -f 文件名称

1
tail -f log

2.6.5 grep

grep命令用于按行提取文本内容,

语法格式为grep [参数] 文件名称

grep命令是用途最广泛的文本搜索匹配工具(即正则表达式)。它虽然有很多参数,但是大多数基本上都用不到。在这里只讲grep命令两个最常用的参数:

  • -n参数用来显示搜索到的信息的行号;
  • -v参数用于反选信息(即没有包含关键词的所有信息行)。

示例

在Linux系统中,/etc/passwd文件保存着所有的用户信息,而一旦用户的登录终端被设置成/sbin/nologin,则不再允许登录系统,因此可以使用grep命令查找出当前系统中不允许登录系统的所有用户的信息:

1
grep /sbin/nologin /etc/passwd

2.7 文件目录管理命令

2.7.1 touch

touch命令用于创建空白文件或设置文件的时间

语法格式为touch [参数] 文件名称

参数 作用
-a 仅修改“读取时间”(atime)
-m 仅修改“修改时间”(mtime)
-d 同时修改atime与mtime

示例

image-20220930163845401

2.7.2 mkdir

mkdir命令用于创建空白的目录,英文全称为“make directory”

语法格式为mkdir [参数] 目录名称

除了能创建单个空白目录外,mkdir命令还可以结合-p参数来递归创建出具有嵌套层叠关系的文件目录。

示例

image-20220930164026826

2.7.3 cp

cp命令用于复制文件或目录,英文全称为“copy”

语法格式为cp [参数] 源文件名称 目标文件名称

参数 作用
-p 保留原始文件的属性
-d 若对象为“链接文件”,则保留该“链接文件”的属性
-r 递归持续复制(用于目录)
-i 若目标文件存在则询问是否覆盖
-a 相当于-pdr(p、d、r为上述参数)

示例

使用touch命令创建一个名为install.log的普通空白文件,然后将其复制为一份名为x.log的备份文件,最后再使用ls命令查看目录中的文件。

image-20220930164528922

2.7.4 mv

mv命令用于剪切或重命名文件,英文全称为“move”

语法格式为mv [参数] 源文件名称 目标文件名称

2.7.5 rm

rm命令用于删除文件或目录,英文全称为“remove”

语法格式为rm [参数] 文件 名称

参数 作用
-f 强制执行
-i 删除前询问
-r 删除目录
-v 显示过程

示例

image-20220930164712029

2.7.6 file

file命令用于查看文件的类型,语法格式为file文件名称

Linux系统中,由于文本、目录、设备等所有这些一切都统称为文件,但是它们又不像Windows系统那样都有后缀,因此很难通过文件名一眼判断出具体的文件类型,这时就需要使用file命令来查看文件类型了。

示例

image-20220930164835218

2.7.7 tar

tar命令用于对文件进行打包压缩或解压,语法格式为tar 参数 文件名称

在Linux系统中,主要使用的是.tar.tar.gz.tar.bz2格式

解压缩的话常用组合参数:-zxvf,或jxvf

参数 作用
-c 创建压缩文件
-x 解开压缩文件
-t 查看压缩包内有哪些文件
-z 用Gzip压缩或解压
-j 用bzip2压缩或解压
-v 显示压缩或解压的过程
-f 目标文件名
-p 保留原始的权限与属性
-P 使用绝对路径来压缩
-C 指定解压到的目录

示例

/root/jdk-8u161-linux-x64.tar.gz解压至指定的目录./下:

1
tar -zxvf /root/jdk-8u161-linux-x64.tar.gz -C ./

CodeSheep(程序羊)制作的常用Linux速查备忘手册,可以参照学习。

下载地址:点我就行

3 管道符、重定向与环境变量

与文件读写操作有关的重定向技术的5种模式:

  • 标准覆盖输出重定向
  • 标准追加输出重定向
  • 错误覆盖输出重定向
  • 错误追加输出重定向
  • 输入重定向

3.1 输入输出重定向

3.1.1 简介

输入重定向是指把文件导入到命令中,而输出重定向则是指把原本要输出到屏幕的数据信息写入到指定文件中。相较于输入重定向,使用输出重定向的频率更高,所以又将输出重定向分为了标准输出重定向和错误输出重定向两种不同的技术,以及覆盖写入与追加写入两种模式。

  • 标准输入重定向(STDIN,文件描述符为0):默认从键盘输入,也可从其他文件或命令中输入。
  • 标准输出重定向(STDOUT,文件描述符为1):默认输出到屏幕。
  • 错误输出重定向(STDERR,文件描述符为2):默认输出到屏幕。

3.1.2 参数

输入重定向:

符号 作用
命令 < 文件 将文件作为命令的标准输入
命令 << 分界符 从标准输入中读入,直到遇见分界符才停止
命令 < 文件1 > 文件2 将文件1作为命令的标准输入并将标准输出到文件2

输出重定向:

符号 作用
命令 > 文件 将标准输出重定向到一个文件中(覆盖)
命令 2> 文件 将错误输出重定向到一个文件中(覆盖)
命令 >> 文件 将标准输出重定向到一个文件中(追加)
命令 2>> 文件 将错误输出重定向到一个文件中(追加)
命令 >> 文件 2>&1 或 命令 &>> 文件 将标准输出与错误输出共同写入到文件中(追加)

3.1.3 示例

  • 通过标准输出重定向将man bash命令原本要输出到屏幕的信息写入到文件readme.txt中,然后显示readme.txt文件中的内容

image-20220930171225616

  • 通过覆盖写入模式向readme.txt文件写入数据

image-20220930171339779

  • 再通过追加写入模式向readme.txt文件写入一次数据

image-20220930171418793

3.2 管道命令符

管道命令符的作用可以用一句话概括为“把前一个命令原本要输出到屏幕的信息当作后一个命令的标准输入”。执行格式为命令A | 命令B | 命令C ...

示例1

找出被限制登录用户的个数。

基础指令:

1
2
grep /sbin/nologin /etc/passwd
wc –l

现在要做的就是把grep搜索命令的输出值传递给wc统计命令,即把原本要输出到屏幕的用户信息列表再交给wc命令作进一步的加工,因此只需要把管道符放到两条命令之间即可。

1
grep /sbin/nologin /etc/passwd | wc -l # 20

示例2

用翻页的形式查看/etc目录中的文件列表及属性信息

1
ls -l /etc/ | more

示例3

搜索与bash有关的进程信息

1
ps aux | grep bash

image-20220930172250098

3.3 命令行的通配符

通配符就是通用的匹配信息的符号,Linux系统中的通配符及含义如下。

通配符 含义
* 任意字符
? 单个任意字符
[a-z] 单个小写字母
[A-Z] 单个大写字母
[a-Z] 单个字母
[0-9] 单个数字
[[:alpha:]] 任意字母
[[:upper:]] 任意大写字母
[[:lower:]] 任意小写字母
[[:digit:]] 所有数字
[[:alnum:]] 任意字母加数字
[[:punct:]] 标点符号

示例1

匹配所有在/dev目录中且以tty开头的文件:

1
ls -l /dev/tty*

image-20220930173142566

示例2

匹配0~9之间的单个数字:

1
ls -l /dev/sda[0-9]

示例3

搜索/etc/目录中所有以.conf结尾的配置文件:

1
ls -l /etc/*.conf

3.4 环境变量

在Linux系统中,变量名称一般都是大写的,命令则都是小写的,这是一种约定俗成的规范。Linux系统中的环境变量是用来定义系统运行环境的一些参数,比如每个用户不同的家目录、邮件存放位置等。可以直接通过变量名称来提取到对应的变量值

可使用env命令查看环境变量:

image-20220930174627715

Linux中最重要的10个环境变量:

变量名称 作用
HOME 用户的主目录(即家目录)
SHELL 用户在使用的Shell解释器名称
HISTSIZE 输出的历史命令记录条数
HISTFILESIZE 保存的历史命令记录条数
MAIL 邮件保存路径
LANG 系统语言、语系名称
RANDOM 生成一个随机数字
PS1 Bash解释器的提示符
PATH 定义解释器搜索用户执行命令的路径
EDITOR 用户默认的文本编辑器

Linux执行命令的过程

第1步:判断用户是否以绝对路径或相对路径的方式输入命令(如/bin/ls),如果是绝对路径则直接执行,否则进入第2步继续判断。

image-20220930174833881

第2步:Linux系统检查用户输入的命令是否为“别名命令”,即用一个自定义的命令名称来替换原本的命令名称。之前在使用rm命令删除文件时,Linux系统都会要求用户确认是否执行删除操作,其实这就是Linux系统为了防止用户误删除文件而特意设置的rm别名命令—rm -i

第3步:Bash解释器判断用户输入的是内部命令还是外部命令。内部命令是解释器内部的指令,会被直接执行;而用户在绝大部分时间输入的是外部命令,这些命令交由步骤4继续处理。可以使用type 命令名称来判断用户输入的命令是内部命令还是外部命令:

1
2
3
4
5
6
[root@VM-24-5-centos ~]# type echo
echo is a shell builtin # 内部命令,直接执行
[root@VM-24-5-centos ~]# type uptime
uptime is /usr/bin/uptime # 外部命令,需要到PATH环境变量中寻找该命令
[root@VM-24-5-centos ~]# type ls
ls is aliased to `ls --color=auto'

第4步:系统在多个路径中查找用户输入的命令文件,而定义这些路径的变量叫作PATH,可以简单地把它理解成是“解释器的小助手”,作用是告诉Bash解释器待执行的命令可能存放的位置,然后Bash解释器就会在这些位置中逐个查找。PATH是由多个路径值组成的变量,每个路径值之间用冒号间隔,对这些路径的增加和删除操作将影响到Bash解释器对Linux命令的查找。

PATH变量:

image-20220930175138667

4 Vim编辑器与Shell命令脚本

4.1 Vim文本编辑器

4.1.1 简介

Vim的发布最早可以追溯到1991年,英文全称为Vi Improved。它也是Vi编辑器的提升版本,其中最大的改进当属添加了代码着色功能,在某些编程场景下还能自动修正错误代码。

Vim编辑器中设置了3种模式:

  • 命令模式:控制光标移动,可对文本进行复制、粘贴、删除和查找等工作。
  • 输入模式:正常的文本录入。
  • 末行模式:保存或退出文档,以及设置编辑环境。

image-20220930175724304

在每次运行Vim编辑器时,默认进入命令模式,此时需要先切换到输入模式后再进行文档编写工作。而每次在编写完文档后需要先返回命令模式,然后再进入末行模式,执行文档的保存或退出操作。Vim编辑器中内置的命令有成百上千种用法。

命令模式中最常用的一些命令:

命令 作用
dd 删除(剪切)光标所在整行
5dd 删除(剪切)从光标处开始的5行
yy 复制光标所在整行
5yy 复制从光标处开始的5行
n 显示搜索命令定位到的下一个字符串
N 显示搜索命令定位到的上一个字符串
u 撤销上一步的操作
p 将之前删除(dd)或复制(yy)过的数据粘贴到光标后面

末行模式主要用于保存或退出文件,以及设置Vim编辑器的工作环境,还可以让用户执行外部的Linux命令或跳转到所编写文档的特定行数。要想切换到末行模式,在命令模式中输入一个冒号就可以了。

末行模式中最常用的一些命令:

命令 作用
:w 保存
:q 退出
:q! 强制退出(放弃对文档的修改内容)
:wq! 强制保存退出
:set nu 显示行号
:set nonu 不显示行号
:命令 执行该命令
:整数 跳转到该行
:s/one/two 将当前光标所在行的第一个one替换成two
:s/one/two/g 将当前光标所在行的所有one替换成two
:%s/one/two/g 将全文中的所有one替换成two
?字符串 在文本中从下至上搜索该字符串
/字符串 在文本中从上至下搜索该字符串

4.1.2 编写简单的文档

  • 新建文档test.txt
1
touch test.txt

或者直接使用:如果存在该文档,则是打开它。如果不存在,则是创建一个临时的输入文件。

1
vim test.txt
  • 打开文档后,默认进入的是Vim编辑器的命令模式。
    • 可以分别使用a、i、o三个键从命令模式切换到输入模式。
    • a键与i键分别是在光标后面一位和光标当前位置切换到输入模式
    • o键是在光标的下面再创建一个空行

image-20221004092334877

  • 敲击键盘的Esc键从输入模式返回命令模式。再输入:wq!切换到末行模式才能完成保存退出操作

image-20221004092452505

4.1.3 配置主机名称

在Linux系统中,主机名大多保存在/etc/hostname文件中,接下来将/etc/hostname配置文件的内容修改为HongyiZeng,步骤如下。

第1步:使用Vim编辑器修改/etc/hostname主机名称文件。

第2步:把原始主机名称删除后追加HongyiZeng。注意,使用Vim编辑器修改主机名称文件后,要在末行模式下执行:wq!命令才能保存并退出文档。

第3步:保存并退出文档,然后使用hostname命令检查是否修改成功。

image-20221004093235145

4.1.4 配置网卡信息

在Linux系统中,一切都是文件,因此配置网络服务的工作其实就是在编辑网卡配置文件,在/etc/sysconfig/network-scripts目录中存放着网卡的配置文件。

在RHEL 5、RHEL 6中,网卡配置文件的前缀为eth,第1块网卡为eth0,第2块网卡为eth1;以此类推。

在RHEL 7中,网卡配置文件的前缀则以ifcfg开始,再加上网卡名称共同组成了网卡配置文件的名字,例如ifcfg-eno16777736

在RHEL 8中,网卡配置文件的前缀依然为ifcfg,区别是网卡名称改成了类似于ens160的样子,不过好在除了文件名发生变化外,网卡参数没有其他大的区别。

image-20221004093719744

4.2 编写Shell脚本

4.2.1 简介

可以将Shell终端解释器当作人与计算机硬件之间的“翻译官”,它作为用户与Linux系统内部的通信媒介,除了能够支持各种变量与参数外,还提供了诸如循环、分支等高级编程语言才有的控制结构特性。Shell脚本命令的工作方式有下面两种。

  • 交互式(Interactive):用户每输入一条命令就立即执行。
  • 批处理(Batch):由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中诸多的命令。

在Shell脚本中不仅会用到前面学习过的很多Linux命令以及正则表达式、管道符、数据流重定向等语法规则,还需要把内部功能模块化后通过逻辑语句进行处理,最终形成日常所见的Shell脚本。

通过查看SHELL变量可以发现,当前系统已经默认使用Bash作为命令行终端解释器了:(Bash是Shell的子集)

1
2
[root@HongyiZeng network-scripts]# echo $SHELL
/bin/bash

4.2.2 编写简单的脚本

Shell脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将.sh后缀加上,以表示是一个脚本文件。

示例

  • 需求:查看当前所在工作路径并列出当前目录下所有的文件及属性信息

image-20221004095917312

1
2
3
4
#!/bin/bash
#An example of shell
pwd
ls -al

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

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

第三、四行的可执行语句就是我们平时执行的Linux命令了。

  • 执行shell脚本

方式一:用Bash解释器命令直接运行Shell脚本文件

1
2
3
4
5
6
7
8
9
10
[root@linuxprobe ~]# bash example.sh
/root
total 60
dr-xr-x---. 15 root root 4096 Oct 12 00:41 .
dr-xr-xr-x. 17 root root 224 Jul 21 05:04 ..
-rw-------. 1 root root 1407 Jul 21 05:09 anaconda-ks.cfg
-rw-------. 1 root root 335 Jul 24 06:33 .bash_history
-rw-r--r--. 1 root root 18 Aug 13 2018 .bash_logout
-rw-r--r--. 1 root root 176 Aug 13 2018 .bash_profile
………………省略部分输出信息………………

方式二:输入完整路径的方式来执行,但默认会因为权限不足而提示报错信息,此时只需要为脚本文件增加执行权限即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@linuxprobe ~]# ./example.sh
bash: ./Example.sh: Permission denied
[root@linuxprobe ~]# chmod u+x example.sh
[root@linuxprobe ~]# ./example.sh
/root
total 60
dr-xr-x---. 15 root root 4096 Oct 12 00:41 .
dr-xr-xr-x. 17 root root 224 Jul 21 05:04 ..
-rw-------. 1 root root 1407 Jul 21 05:09 anaconda-ks.cfg
-rw-------. 1 root root 335 Jul 24 06:33 .bash_history
-rw-r--r--. 1 root root 18 Aug 13 2018 .bash_logout
-rw-r--r--. 1 root root 176 Aug 13 2018 .bash_profile
………………省略部分输出信息………………

4.2.3 接收用户参数

Linux系统中的Shell脚本语言内设了用于接收命令参数的变量,变量之间使用空格间隔。

  • $0对应的是当前Shell脚本程序的名称
  • $#对应的是总共有几个参数
  • $*对应的是所有位置的参数值
  • $?对应的是显示上一次命令的执行返回值
  • $1、$2、$3……分别对应着第N个位置的参数值

image-20221004100829743

示例

1
2
3
4
5
[root@HongyiZeng ~]# vim example.sh 
#!/bin/bash
echo "当前脚本名称为$0"
echo "总共有$#个参数,分别是$*"
echo "第1个参数是$1"

执行该脚本:

1
2
3
4
[root@HongyiZeng ~]# bash example.sh one two
当前脚本名称为example.sh
总共有2个参数,分别是one two
第1个参数是one

4.2.4 判断用户参数

Shell脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字0,否则便返回非零值。切记,条件表达式两边均应有一个空格。

image-20221004101230874

按照测试对象来划分,条件测试语句可以分为4种:

  • 文件测试语句
  • 逻辑测试语句
  • 整数值比较语句
  • 字符串比较语句
① 文件测试

文件测试即使用指定条件来判断文件是否存在或权限是否满足等情况的运算符,具体参数如下所示:

操作符 作用
-d 测试文件是否为目录类型
-e 测试文件是否存在
-f 判断是否为一般文件
-r 测试当前用户是否有权限读取
-w 测试当前用户是否有权限写入
-x 测试当前用户是否有权限执行

示例

  • 判断/etc/fstab是否为一个目录类型的文件,然后通过Shell解释器的内设$?变量显示上一条命令执行后的返回值。如果返回值为0,则目录存在;如果返回值为非零的值,则意味着它不是目录,或这个目录不存在。
1
2
3
[root@HongyiZeng ~]# [ -d /etc/fstab ]     
[root@HongyiZeng ~]# echo $?
1
  • 判断/etc/fstab是否为一般文件,如果返回值为0,则代表文件存在,且为一般文件
1
2
3
[root@HongyiZeng ~]# [ -f /etc/fstab ] 
[root@HongyiZeng ~]# echo $?
0
② 逻辑测试
  • 与或非:&& || !

示例

  • 判断/dev/cdrom文件是否存在,若存在则输出Exist字样
1
2
[root@HongyiZeng ~]# [ -e /dev/cdrom ] && echo "Exist"
Exist
③ 整数值比较

整数比较运算符仅是对数字的操作,不能将数字与字符串、文件等内容一起操作。因为等号与赋值命令符冲突,大于号和小于号分别与输出重定向命令符和输入重定向命令符冲突。因此一定要使用规范的整数比较运算符来进行操作。

操作符 作用
-eq 是否等于
-ne 是否不等于
-gt 是否大于
-lt 是否小于
-le 是否等于或小于
-ge 是否大于或等于

示例

  • 测试10是否大于10(通过输出的返回值内容来判断):
1
2
3
[root@HongyiZeng ~]# [ 10 -gt 10 ]
[root@HongyiZeng ~]# echo $?
1
④ 字符串比较

字符串比较语句用于判断测试字符串是否为空值,或两个字符串是否相同。它经常用来判断某个变量是否未被定义(即内容为空值)。

操作符 作用
= 比较字符串内容是否相同
!= 比较字符串内容是否不同
-z 判断字符串内容是否为空

示例

1
2
3
[root@HongyiZeng ~]# [ -z $SHELL ]
[root@HongyiZeng ~]# echo $?
1

4.3 流程控制语句

4.3.1 条件测试语句

if条件语句的单分支结构由ifthenfi关键词组成。

  • 单分支

image-20221005103000810

示例:使用单分支的if条件语句来判断/media/cdrom目录是否存在,若不存在就创建这个目录,反之则结束条件判断和整个Shell脚本的执行。

1
2
3
4
5
6
7
8
9
10
[root@HongyiZeng ~]# vim mkcdrom.sh
#!/bin/bash
DIR="/media/cdrom"
if [ ! -d $DIR ]
then
mkdir -p $DIR
fi
[root@HongyiZeng ~]# bash mkcdrom.sh
[root@HongyiZeng ~]# ls -ld /media/cdrom/
drwxr-xr-x 2 root root 4096 Oct 5 10:35 /media/cdrom/
  • 双分支:由ifthenelsefi关键词组成

image-20221005103705478

示例:验证某台主机是否在线,然后根据返回值的结果,要么显示主机在线信息,要么显示主机不在线信息。

1
2
3
4
5
6
7
8
9
10
11
[root@HongyiZeng ~]# vim chkhost.sh
#!/bin/bash
ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
if [ $? -eq 0 ]
then
echo "Host $1 is on-line."
else
echo "Host $1 is off-line."
fi
[root@HongyiZeng ~]# bash chkhost.sh 127.0.0.1
Host 127.0.0.1 is on-line.

$?变量,作用是显示上一次命令的执行返回值。若前面的那条语句成功执行,则$?变量会显示数字0,反之则显示一个非零的数字(可能为1,也可能为2,取决于系统版本)。

  • 多分支:由ifthenelseeliffi关键词组成

image-20221005104351523

示例:判断用户输入的分数在哪个成绩区间内,然后输出如Excellent、Pass、Fail等提示信息。在Linux系统中,read是用来读取用户输入信息的命令,能够把接收到的用户输入信息赋值给后面的指定变量,-p参数用于向用户显示一些提示信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@HongyiZeng ~]# vim chkscore.sh
#!/bin/bash
read -p "Enter your score(0-100):" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then
echo "$GRADE is Excellent"
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
echo "$GRADE is Pass"
else
echo "$GRADE is Fail"
fi
[root@HongyiZeng ~]# bash chkscore.sh
Enter your score(0-100):88
88 is Excellent
[root@HongyiZeng ~]# bash chkscore.sh
Enter your score(0-100):80
80 is Pass

4.3.2 for条件循环语句

for循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理。

image-20221005104554516

  • 示例1:从列表文件中读取多个用户名,然后为其逐一创建用户账户并设置密码。首先创建用户名称的列表文件users.txt,每个用户名称单独一行。编写Shell脚本addusers.sh。在脚本中使用read命令读取用户输入的密码值,然后赋值给PASSWD变量,并通过-p参数向用户显示一段提示信息,告诉用户正在输入的内容即将作为账户密码。在执行该脚本后,会自动使用从列表文件users.txt中获取到所有的用户名称,然后逐一使用“id用户名”命令查看用户的信息,并使用$?判断这条命令是否执行成功,也就是判断该用户是否已经存在。
1