首页 > 技术文章 > 石一歌的Linux笔记

faetbwac 2022-01-07 11:39 原文

走近 Linux 系统

开机

会启动许多程序。它们在 Windows 叫做’服务 " (service) , 在 Linux 就叫做 "守护进程" (daemon)。 最高权限账户为 root, 可以操作一切!

​ 登录方式有三种:

  • 命令行登录
  • SSH 登录 (远程)
  • 图形界面登录

关机&重启

在 linux 领域内大多用在服务器上, 很少遇到关机的操作。毕竟服务器上跑一个服务是永无止境的, 除非特殊情况下, 不得已才会关机。

sync #将数据由内存同步到硬盘中。
shutdown #关机指令,你可以man shutdown 来看一下 帮助文档。例如你可以运行如下命令关机:
shutdown -h 10 #这个命令告诉大家,计算机将在10分钟后关机
shutdown -h now#立马关机
shutdown -h 20:25 #系统会在今天20:25关机
shutdown -h +10 #十分钟后关机
shutdown -r now #系统立马重启
shutdown -r +10 #系统十分钟后重启
reboot #就是重启,等同于shutdown -r now
halt #关闭系统,等同于shutdown -h now和poweroff

最后总结:不管是重启还是关闭系统,首先要运行 sync 命令,把内存中的数据写到磁盘中,执行命令之后没有返回消息则表明运行成功

清屏&关闭终端

清屏操作相当于翻页,前面的内容仍可以查看。

关闭终端操作,首先会退出终端,其次会断开ssh连接。即root切换普通用户后关闭终端会退出普通用户。

clear
CTRL+L
exit

系统时间

-p, --pretty   以漂亮的格式显示正常运行时间
-h, --help     显示此帮助并退出
-s, --since    系统启动以来
-V, --version  输出版本信息并退出
uptime -p

系统目录

  1. 一切皆文件
  2. 根目录 / , 所有的文件都挂载在这个节点下
ls / #查看当前下的目录

QQ截图20220105112931

目录解释

  • /bin:bin 是 Binary 的缩写, 这个目录存放着最经常使用的命令。
  • /boot: 这里存放的是启动 Linux 时使用的一些核心文件,包括一些连接文件以及镜像文件。
  • /dev : dev 是 Device(设备) 的缩写, 存放的是 Linux 的外部设备,在 Linux 中访问设备的方式和访问文件的方式是相同的。
  • /etc: 这个目录用来存放所有的系统管理所需要的配置文件和子目录。
  • /home:用户的主目录,在 Linux 中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的。
  • /lib:这个目录里存放着系统最基本的动态连接共享库,其作用类似于 Windows 里的 DLL 文件。
  • /lost+found:这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。
  • /media:linux 系统会自动识别一些设备,例如 U 盘、光驱等等,当识别后,linux 会把识别的设备挂载到这个目录下。
  • /mnt:系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在 / mnt / 上,然后进入该目录就可以查看光驱里的内容了。
  • /opt:这是给主机额外安装软件所摆放的目录。比如你安装一个 ORACLE 数据库则就可以放到这个目录下。默认是空的。
  • /proc:这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。
  • /root:该目录为系统管理员,也称作超级权限者的用户主目录。
  • /sbin:s 就是 Super User 的意思,这里存放的是系统管理员使用的系统管理程序。
  • /srv:该目录存放一些服务启动之后需要提取的数据。
  • /sys:这是 linux2.6 内核的一个很大的变化。该目录下安装了 2.6 内核中新出现的一个文件系统 sysfs 。
  • /tmp:这个目录是用来存放一些临时文件的。 用完即丢的文件可以放在这个目录下
  • /usr:这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于 windows 下的 program files 目录。
    • /usr/bin: 系统用户使用的应用程序。
    • /usr/sbin: 超级用户使用的比较高级的管理程序和系统守护程序。
    • /usr/src: 内核源代码默认的放置目录。
  • /var:这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。
  • /run:是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。
  • /www:存放服务器网站相关的资源,环境,网站的项目(宝塔创建)。

常见技巧

Tab命名补齐

  • 在输入命令或文件的前几个字符后,按TAB键可自动补齐剩余字符串。
  • 如果出现多个命令或文件有相同的前缀,Shell将会列出具有该前缀的所有命令或文件。帮助用户完成需要的输入。
  • 命令补齐需要连续按两次Tab键,文件名补齐需要一次Tab键。

历史命令

  • 用户需要查看曾经执行过的操作时,按键,即可翻看命令历史

  • -c					清空输入历史
    -w					输入历史存入磁盘空间~/.bash_history
    history
    

通配符

通配符 含义
星号(*) 匹配任意长度的字符串
问号(?) 匹配一个长度的字符
方括号([...]) 匹配其中指定的一个字符
方括号([-]) 匹配指定的一个范围
方括号([^...]) 除了指定的字符,均可匹配

管道符

  • | 可以实现将第一个命令的输出作为第二个命令的输入

基本命令

命令提示符

通常情况下Shell命令行提示符采用以下的格式。

[root@faetbwac ~]# 
  • 用户在提示符后面输入命令并按Enter键,向系统发送指令。
  • username:用户名,即当前登录用户的用户名。
  • hostname:主机名,即系统的主机名。
  • direction:目录名,即当前用户所处的路径,“~”表示在用户主目录下;“/”表示在根目录(类似于Windows系统下的C盘)下,即系统目录下。
  • $:Shell提示符,表示当前用户为普通用户。如果当前用户为超级用户(管理员),则提示符为“#”。

命令格式

一般情况下,命令的3要素为:命令名称、附加选项、参数。其中命令名称,附加选项与参数则一般是可选项(即根据实际情况选定)。命令格式一般如下所示。

  • Command:命令名称,可以为Shell命令或执行程序,严格区分大小写。
  • Options:附加选项,通常情况下,用户若希望命令可以实现更加精确或更加全面的功能,则需要在命令后添加选项,指定命令动作。
  • Argument:参数,一般用来指定作用对象或目标,可以是特定的值。有时可以添加多个参数。
  • •需要注意的是,输入命令时需要将上述3要素用空格隔开;如果多个命令需要同时输入操作系统,则命令与命令之间使用“;”隔开;如果一条命令不能在一行输入完成,则需要在本行结尾处使用分隔符“\”,表示本行未输入完整。

目录管理

cd: 切换目录

cd:#切换目录命令!
./:#当前目录
/:#绝对路径
cd..:#返回上一级目录
cd ~:#回到当前的用户目录
pwd :#显示当前用户所在的目录

ls(列出目录)

-a, --all                  不隐藏任何以. 开始的项目
-i, --inode                打印每个文件的索引号
-l                         使用较长格式列出信息
-1                         每行列出一个文件
ls -al 查看全部的文件包括隐藏文件的属性和权限

mkdir 创建目录

-m, --mode=MODE   设置文件模式
-p, --parents     如果存在错误,请根据需要创建父目录
mkdir -p test2/test3/test4 # 递归创建层级目录

rmdir 删除目录

rmdir 仅能删除空的目录, 如果下面存在文件, 需要先删除文件

-p, --parents   删除目录及其祖先
-v, --verbose   为处理的每个目录输出一个诊断
rmdir -p test2/test3/test4 #递归删除目录

cp(复制文件或者目录)

-d                            复制时保留链接
-f, --force                   如果无法打开现有目标文件,请将其删除并重试
-i, --interactive             覆盖前提示
-P, --no-dereference          不跟随源文件中的符号链接
-R, -r, --recursive           递归复制目录及其子目录内的所有内容
-a, --archive                 等于-dR --preserve=all
cp install.sh cqhstudy #将当前目录下的install.sh 复制到cqhstudy文件夹中

rm 移除文件或者目录

-i                    每次搬家前都要提示
-f, --force           忽略不存在的文件和参数,从不提示t
-r, -R, --recursive   递归删除目录及其内容
rm -rf install.sh/ #删除系统中的install.sh

mv 移动文件或者目录 | 重命名文件

-f, --force                  覆盖前不询问
-i, --interactive            覆盖前询问
-u, --update                 仅当源文件比目标文件新或目标文件丢失时才移动
mv install.sh cqhstudy #移动文件
mv cqhstudy cqhstudy2 #重命名文件夹名

文件搜索

正则表达式选择与解释:
-i, --ignore-case         忽略大小写
混杂:
-s, --no-messages         抑制错误消息
-v, --invert-match        选择不匹配的行
输出控制:
-n, --line-number         输出的同时打印行号
-h, --no-filename         输出时不显示文件名前缀
-r, --recursive           递归处理目录
-l, --files-with-matches  print only names of FILEs containing matches
grep [选项]... PATTERN [FILE]...
-depth                     使用深度级别的查找过程方式,在指定的目录中优先查找文件内容
-moumt                     不在其他文件系统(vfat等)的目录和文件中查找
-name                      按照名字查找,支持通配符“*”和“?”
-user                      按照文件所属用户查找
-print                     输出搜索结果,并且打印
find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

网络

ping #用来查看网络是否连通
ifconfig #查看网络 和Windows的ipconfig是一样的

基本属性

文件基本属性解释

​ Linux 系统是一种典型的多用户系统, 不同的用户处于不同的地位, 拥有不同的权限。为了保护系统的安全性, Linux 系统对不同的用户访问同一文件 (包括目录文件) 的权限做了不同的规定。

在 Linux 中我们可以使用ll或者 ls -l 命令来显示一个文件的属性以及文件所属的用户和组, 如:

  • 当为 [d] 则是目录
  • 当为 [-] 则是文件;
  • 若是 [l] 则表示为链接文档( link file);
  • 若是 [b] 则表示为装置文件里面的可供储存的接口设备(可随机存取装置) ;
  • 若是 [c] 则表示为装置文件里面的串行端口设备, 例如键盘、鼠标( 一次性读取装置)。

​ 接下来的字符中, 以三个为一组, 且均为 [rwx] 的三个参数的组合。 其中,[r]代表可读 (read)、[w] 代表可写 (write)、[x] 代表可执行(execute)。 要注意的是, 这三个权限的位置不会改变, 如果没有权限, 就会出现减号 [-] 而已。
每个文件的属性由左边第一部分的 10 个字符来确定 (如下图) :
QQ截图20220105152447

从左至右用 0-9 这些数字来表示。
第 0 位确定文件类型, 第 1-3 位确定属主 (该文件的所有者) 拥有该文件的权限。第 4-6 位确定属组 (所有者的同组用户)拥有该文件的权限, 第 7-9 位确定其他用户拥有该文件的权限。

其中:

  • 第 1、4、7 位表示读权限, 如果用 "r" 字符表示, 则有读权限, 如果用 "-“字符表示, 则没有读权限;
  • 第 2、5、8 位表示写权限, 如果用 "W" 字符表示, 则有写权限, 如果用”-“字符表示没有写权限;
  • 第 3、6、9 位表示可执行权限, 如果用 "x" 字符表示, 则有执行权限, 如果用”-" 字符表示, 则没有执行权限。

对于文件来说, 它都有一个特定的所有者, 也就是对该文件具有所有权的用户。 同时, 在 Linux 系统中, 用户是按组分类的, 个用户属于一个或多个组。 文件所有者以外的用户又可以分为文件所有者的同组用户和其他用户。
因此, Linux 系统按文件所有者、文件所有者同组用户和其他用户来规定了不同的文件访问权限。

修改文件基本属性

  1. chgrp : 更改文件属组
-R, --recursive        递归操作文件和目录
-c, --changes          喜欢冗长,但只在做出更改时报告
-f, --silent, --quiet  抑制大多数错误消息
chgrp [-R] root www
  1. chown : 更改文件属主, 也可以同时更改文件属组
-c, --changes          喜欢冗长,但只在做出更改时报告
-f, --silent, --quiet  抑制大多数错误消息
chown [-R] 属主名 文件名
chown [-R] 属主名: 属组名 文件名
  1. chmod : 更改文件 9 个属性
-c, --changes          喜欢冗长,但只在做出更改时报告
-f, --silent, --quiet  抑制大多数错误消息
-v, --verbose          为处理的每个文件输出一个诊断
chmod [-R] xyz 文件或目录
chomd 777 文件或目录 #文件赋予所有用户可读可执行! 

Linux 文件属性有两种设置方法, 一种是数字, 一种是符号。
Linux 文件的基本权限就有九个, 分别是 owner/group/others 三种身份各有自己的 read/write/execute 权限。
先复习一下刚刚上面提到的数据: 文件的权限字符为: [-rwxrwxrwx],这九个权限是三个三个一组的! 其中, 我们可以使用字来代表各个权限, 各权限的分数对照表如下:
r:4 w:2 x:1
可读可写不可执行 rw- 6
可读可写可执行 rwx 7

文件内容查看

Linux 系统中使用以下命令来查看文件的内容:

  • cat 由第一行开始显示文件内容
  • tac 从最后一行开始显示,可以看出 tac 是 cat 的倒着写!
  • nl 显示的时候, 顺道输出行号!
  • more 一页一页的显示文件内容(空格表示翻页,enter 代表向下看下一行,:f 输出文件名和当前行的行号)
  • less 与 more 类似, 但是比 more 更好的是, 他可以往前翻页!(空格翻页,上下键代表上下翻动页面,q:退出 命令,/ :向下查询查找字符串 ,?:向上查询查找字符串, n: 重复前一个搜索(与 / 或 ? 有关), N:反向重复前一个搜索(与 / 或 ? 有关))
  • head 只看头几行 通过 - n 参数来控制显示几行
  • tail 只看尾巴几行 通过 - n 参数来控制显示几行

你可以使用 man 命令来查看各个命令的使用文档, 如: man [命令]

硬链接和软链接

Linux 链接分为两种:硬链接、软链接
硬链接:相当于指针,删除源文件和硬链接文件都不会直接删除文件本身。
软链接:相当于 Windows 下的快捷方式,删除源文件软连接即失效。

创建文件

touch 文件名

建立硬链接

ln 源文件 硬链接文件

建立软连接

ln -s 源文件 硬链接文件

输入文字

echo "text" >> 文件

压缩打包

压缩

-c, --stdout      在标准输出上写入,保持原始文件不变
-d, --decompress  解压
-l, --list        列出压缩文件内容
-L, --license     显示软件许可证
-r, --recursive   对目录进行递归操作
-v, --verbose     详细模式
gzip [OPTION]... [FILE]...

打包

-c, --create               创建一个新归档
-r, --append               追加文件至归档结尾
-u, --update               仅追加比归档中副本更新的文件
-x, --extract, --get       从归档中解出文件
-v, --verbose              详细地列出处理的文件
-f, --file=ARCHIVE         使用归档文件或 ARCHIVE 设备
-j, --bzip2                通过 bzip2 过滤归档
-z, --gzip, --gunzip, --ungzip   通过 gzip 过滤归档
tar [选项...] [FILE]...

Vim 编辑器

键盘图

QQ截图20220105185906

三种使用模式

命令模式 (Command mode) , 输入模式 (Insert mode) 和 底线命令模式 (Lastline mode)。

命令模式

用户刚刚启动 Vi/Vim , 便进入了命令模式。
此状态下敲击键盘动作会被 Vim 识别为命令, 而非输入字符。
常用命令:

  • i 切换到输入模式, 以输入字符。
  • x 删除当前光标所在处的字符。
  • : 切换到底线命令模式, 以在最底一行输入命令。

输入模式

  • 字符按键以及 Shift 组合,输入字符
  • ENTER,回车键,换行
  • BACK SPACE,退格键,删除光标前一个字符
  • DEL,删除键,删除光标后一个字符
  • 方向键,在文本中移动光标
  • HOME/END,移动光标到行首 / 行尾
  • Page Up/Page Down,上 / 下翻页
  • Insert,切换光标为输入 / 替换模式,光标将变成竖线 / 下划线
  • ESC,退出输入模式,切换到命令模式

底线命令模式

  • q 退出程序
  • w 保存文件
  • ESC 随时退出底线命令模式。

按键说明

第一部分:一般模式可用的光标移动、复制粘贴、搜索替换等

移动光标的方法
h 或 向左箭头键(←) 光标向左移动一个字符
j 或 向下箭头键(↓) 光标向下移动一个字符
k 或 向上箭头键(↑) 光标向上移动一个字符
l 或 向右箭头键(→) 光标向右移动一个字符
[Ctrl] + [f] 屏幕『向下』移动一页,相当于 [Page Down]按键 (常用)
[Ctrl] + [b] 屏幕『向上』移动一页,相当于 [Page Up] 按键 (常用)
[Ctrl] + [d] 屏幕『向下』移动半页
[Ctrl] + [u] 屏幕『向上』移动半页
+ 光标移动到非空格符的下一行
- 光标移动到非空格符的上一行,配置文件中空格较多
n n 表示『数字』 。快捷切换光标, 数字 + 空格
0或功能键[Home] 这是数字『 0 』:移动到这一行的最前面字符处 (常用)
$ 或功能键[End] 移动到这一行的最后面字符处(常用)
H 光标移动到这个屏幕的最上方那一行的第一个字符
M 光标移动到这个屏幕的中央那一行的第一个字符
L 光标移动到这个屏幕的最下方那一行的第一个字符
G 移动到这个档案的最后一行(常用)
nG n 为数字。移动到这个档案的第 n 行。(可配合 :set nu)
gg 移动到这个档案的第一行,相当于 1G 啊!(常用)
n n 为数字。光标向下移动 n 行(常用)
搜索替换
/word 向光标之下寻找一个名称为 word 的字符串。
?word 向光标之上寻找一个字符串名称为 word 的字符串。
n 这个 n 是英文按键。代表重复前一个搜寻的动作。
N 这个 N 是英文按键。与 n 刚好相反,为『反向』进行前一个搜寻动作。
删除、复制与粘贴
x, X 在一行字当中,x 为向后删除一个字符 (相当于 [del] 按键), X 为向前删除一个字符(相当于 [backspace] 亦即是退格键) (常用)
nx n 为数字,连续向后删除 n 个字符。举例来说,我要连续删除 10 个字符, 『10x』。
dd 删除游标所在的那一整行(常用)
ndd n 为数字。删除光标所在的向下 n 行,例如 20dd 则是删除 20 行 (常用)
d1G 删除光标所在到第一行的所有数据
dG 删除光标所在到最后一行的所有数据
d$ 删除游标所在处,到该行的最后一个字符
d0 那个是数字的 0 ,删除游标所在处,到该行的最前面一个字符
yy 复制游标所在的那一行(常用)
nyy n 为数字。复制光标所在的向下 n 行,例如 20yy 则是复制 20 行(常用)
y1G 复制游标所在行到第一行的所有数据
yG 复制游标所在行到最后一行的所有数据
y0 复制光标所在的那个字符到该行行首的所有数据
y$ 复制光标所在的那个字符到该行行尾的所有数据
p, P p 为将已复制的数据在光标下一行贴上,P 则为贴在游标上一行!举例来说,我目前光标在第 20 行,且已经复制了 10 行数据。则按下 p 后, 那 10 行数据会贴在原本的 20行之后,亦即由 21 行开始贴。但如果是按下 P 呢?那么原本的第 20 行会被推到变成30 行。(常用)
J 将光标所在行与下一行的数据结合成同一行
c 重复删除多个数据,例如向下删除 10 行,[ 10cj ]
u 复原前一个动作。(常用)
[Ctrl]+r 重做上一个动作。(常用)

第二部分:一般模式切换到编辑模式的可用的按钮说明

进入输入或取代的编辑模式
i, I 进入输入模式(Insert mode):i 为『从目前光标所在处输入』, I 为『在目前所在行的第一个非空格符处开始输入』。(常用)
a, A 进入输入模式(Insert mode):a 为『从目前光标所在的下一个字符处开始输入』,A 为『从光标所在行的最后一个字符处开始输入』。(常用)
o, O 进入输入模式(Insert mode):这是英文字母 o 的大小写。o 为『在目前光标所在的下一行处输入新的一行』;O 为在目前光标所在处的上一行输入新的一行!(常用)
r, R 进入取代模式(Replace mode):r 只会取代光标所在的那一个字符一次;R会一直取代光标所在的文字,直到按下 ESC 为止;(常用)
[Esc] 退出编辑模式,回到一般模式中(常用)

第三部分:一般模式切换到指令行模式的可用的按钮说明

指令行的储存、离开等指令
:w 将编辑的数据写入硬盘档案中(常用)
:w! 若文件属性为『只读』时,强制写入该档案。
:q 离开 vi (常用)
:q! 若曾修改过档案,又不想储存,使用 ! 为强制离开不储存档案。
:wq 储存后离开,若为 :wq! 则为强制储存后离开 (常用)
ZZ 这是大写的 Z 喔!若档案没有更动,则不储存离开,若档案已经被更动过,则储存后离开!
:w [filename] 将编辑的数据储存成另一个档案(类似另存新档)
:r [filename] 在编辑的数据中,读入另一个档案的数据。亦即将『filename』 这个档案内容加到游标所在行后面
:n1,n2 w [filename] 将 n1 到 n2 的内容储存成 filename 这个档案。
:! command 暂时离开 vi 到指令行模式下执行 command 的显示结果!例如『:! ls /home』即可在 vi 当中看 /home 底下以 ls 输出的档案信息!
:set nu 设置行号,代码中经常会使用! 显示行号,设定之后,会在每一行的前缀显示该行的行号
:set nonu 与 set nu 相反,为取消行号!

账号管理

查看用户

cat /etc/passwd
cat /etc/passwd|grep 用户名

查看密码

cat /etc/shadow

添加用户

理解一下本质: Linux 中一切皆文件,添加用户即写入用户信息在 /etc/passwd

-m: 自动创建这个用户的主目录 /home/[username]
-c 指定注释性描述
-d 指定用户主日录,使用-m可以创建主日录(主日录不存在的情况下)
-g 指定用户所属的用户组
-G 指定用户所属的附加组
-s 指定用户的登录Shel1
-u 指定用户的标识号
useradd - 选项 用户名 

删除用户

userdel -r [username] #删除用户 及其目录

修改用户

usermode -d /home/[username] [username] #修改用户目录

切换用户

$ 表示普通用户,# 表示超级用户

 su [选项] [-] [USER [参数]...]

将有效用户 id 和组 id 更改为 USER 的 id。
单个 - 视为 -l。如果未指定 USER,将假定为 root。

选项:
 -m, -p, --preserve-environment  不重置环境变量
 -g, --group <组>             指定主组
 -G, --supp-group <组>        指定一个辅助组

 -, -l, --login                  使 shell 成为登录 shell
 -c, --command <命令>            使用 -c 向 shell 传递一条命令
 --session-command <命令>        使用 -c 向 shell 传递一条命令
                                 而不创建新会话
 -f, --fast                      向shell 传递 -f 选项(csh 或 tcsh)
 -s, --shell <shell>             若 /etc/shells 允许,则运行 shell

 -h, --help     显示此帮助并退出
 -V, --version  输出版本信息并退出
  • 切换用户的命令为: su username [username 是你的用户名]
  • 从普通用户切换到 root 用户, 还可以使用命令: sudo su
  • 在终端输入 exit 或 logout 或使用快捷方式 ctrl+d , 可以退回到原来用户, 其实 ctrl+d 也是执行的 exit 命令
  • 在切换用户时, 如果想在切换用户之后使用新用户的工作环境, 可以在 su 和 username 之间加, 例如: [su- root]

用户密码

  • 超级用户修改用户密码
passwd [username] 
new password #新密码
re password #重复新密码
  • 普通用户修改密码
passwd
(current)UNIX password: #当前密码
new password #新密码
re password #重复新密码

锁定用户

passwd -f [username] #强制用户下次登录时修改口令
passwd -l [username] #锁定用户 防止用户登录
passwd -d [username] #清空密码 防止用户登录
passwd -u [username] #口令解锁

用户组管理

  		​		每个用户都有一个用户组, 系统可以对一个用户组中的所有用户进行集中管理 (开发、测试、运维)。不同 Linux 系统对用户组的规定有所不同, 如 Linux 下的用户属于与它同名的用户组, 这个用户组在创建用户时同时创建。 
  		​		用户组的管理涉及用户组的添加、删除和修改。组的增加、删除和修改实际上就是对 /etc/group 文件的更新。

查看用户组

cat /etc/group

创建用户组

创建完用户组后可以得到一一个组的识别码, 这个识别码是可以指定的! 如果不指定就是自增 1

-g #指定新用户组的标识号(GID)
-o #与-g同时使用,表示新用户组的GID可以与系统已有用户组的GID相同
groupadd [group]

删除用户组

groupdel [group]

修改用户组

-g #指定新的组标识号(GID)
-o #与-g同时使用,表示新指定的GID可以与系统中已存在的GID相同
-n #将用户组的名字改为新名字
groupmod -g 777 [group] #修改识别码
groupmod -n [newgroup] [group] #修改用户组

切换用户组

newgrp [group] 

用户账户文件

  • /etc/passwd

    用户名:口令 (登录密码,不可见):用户标识号:组标识号:注释性描述:主目录:登录She11 
    
  • /etc/shadow (密码)

    登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效时间:标志
    
  • /etc/group

    组名:口令:组标识号:组内用户列表
    

磁盘管理

  • 查看当前系统内存使用情况

    • free
      
  • 列出文件系统整体的磁盘使用量

    • 用法:df [选项]... [文件]...
      选项
        -a, --all             包括伪的、重复的、不可访问的文件系统
        -h, --human-readable  以可读格式打印尺寸
        -k                    即--block-size=1K
        -T, --print-type      打印文件系统类型
      
  • 检查磁盘空间使用量

    • -a #查看隐藏
      du 
      
  • 检查根目录下每个文件容量

    • du -sm /*  
      
  • 查看硬盘分区情况以及硬盘分区操作

    • fdisk
      用法:
       fdisk [选项] <磁盘>    更改分区表
       fdisk [选项] -l <磁盘> 列出分区表
       fdisk -s <分区>        给出分区大小(块数)
      
      选项:
       -b <大小>             扇区大小(512、1024、2048或4096)
       -c[=<模式>]           兼容模式:“dos”或“nondos”(默认)
       -h                    打印此帮助文本
       -u[=<单位>]           显示单位:“cylinders”(柱面)或“sectors”(扇区,默认)
       -v                    打印程序版本
       -C <数字>             指定柱面数
       -H <数字>             指定磁头数
       -S <数字>             指定每个磁道的扇区数
      
  • 磁盘挂载

    • 挂载

      -a 读取/etcl fstab文件中的内容,将文件中记录的文件系统挂载发到对应的目录下
      -l 列出当前系统已挂载的设备、文件系统名称和挂载,点
      -t 指定文件系统类型实现挂载
      -f 用于除错。mount不执行实际挂上的动作,而是模拟整个挂载的过程。
      mount [-lhV]
      mount -a [选项]
      mount [选项] [--source] <源> | [--target] <目录>
      mount [选项] <源> <目录>
      mount <操作> <挂载点> [<目标>]
      
    • 卸载

      -a, --all               卸载所有文件系统
      -f, --force             强制卸载(遇到不响应的 NFS 系统时)
      umount [-hV]
      umount -a [选项]
      umount [选项] <源> | <目录>
      

进程管理

  1. 在 Linux 中 , 每一个程序都是有自己的一个进程, 每一个进程都有一个 id 号!
  2. 每一个进程呢, 都会有一个父进程!
  3. 进程可以有两种存在方式: 前台/后台
  4. 一般的话服务都是后台运行的,基本的程序都是前台运行的
  • 查看当前系统中正在执行的各种进程的信息

    • -a #显示当前终端所有的进程信息 
      -u #以用户的信息显示进程 
      -x #显示后台运行进程的参数
      -w #屏幕加宽
      ps
      
    • ps -aux|grep 进程名  #过滤进程信息
      # | 在Linux中这个叫管道符   A输出作为B的参数
      # grep 查找文件中符合条件的字符串
      
    • ps -ef|grep 进程名 #过滤进程信息,带有父进程id
      
    • -p #显示父id
      -u #显示用户组
      pstree -pu #将所有进程以树状图显示
      
    • top #动态显示进程列表
      
  • 杀死进程

    -l <信息编号>  若不加<信息编号>选项,则 -l 参数会列出全部的信息名称。
    -s <信息名称或编号>  指定要送出的信息。
    [程序]  [程序]可以是程序的PID或是PGID,也可以是工作编号。
    kill [-s <信息名称或编号>][程序] 或 kill [-l <信息编号>]
    
    # 常见信号
    1 (HUP):重新加载进程。
    9 (KILL):杀死一个进程。
    15 (TERM):正常停止一个进程。
    

C语言编程环境

GCC

GCC(GNU Compiler Collection)是一款编译语言编译器,此项目最早由GNU计划的发起者理查德· 斯托曼开始实施。第一版GCC于1987年发行,最初的GCC代表GNU C Compiler,即GNU的C语言编译器。后来经过不断地发展,GCC适应了C++、Objective-C、Java、Go等更多编译语言。GCC最重要的特点为实现跨硬件平台编译,即可在当前的CPU平台上为其他体系结构的硬件平台(ARM、MIPS、X86、PowerPC)开发软件,目前这一方式被广泛应用于嵌入式开发中。

GCC编译器的工作目的就是将开发者编写的语言代码变成可以被机器识别的二进制码。

  • 分析器:将源程序代码转换为汇编语言。
  • 汇编器:将汇编语言的代码转换为CPU可以执行的字节码。
  • 链接器:将汇编器生成的单独的目标文件组合成可执行的应用程序。
  • 标准C库:提供对核心函数的支持,如果应用程序使用到C库中的函数,C库就会通过链接器与源代码连接,来生成最终的可执行程序。

编译流程

  • 预处理
    • 在预处理阶段GCC主要处理带“#”的指令,如#include(头文件)、#define(宏定义)等,并删除注释、添加行号和文件名标识。例如,例中的代码,在预处理的阶段将把包含的头文件stdio.h添加进来(解析头文件),然后生成预处理文件test.i。
    • 预处理可以通过GCC编译器单步编译实现,只需在命令gcc中添加选项“-E”即可。该选项的作用就是让编译器执行完预处理后停止编译过程。
  • 编译
    • 编译阶段中,GCC对预处理文件进行词法分析、语法分析、语义分析,检查代码的规范性。确认无误后,GCC将代码翻译为汇编语言。同样,编译也可以使用GCC编译器进行单步操作。添加选项“-S”即可完成编译操作,而不会继续执行汇编处理。
  • 汇编
    • 汇编阶段汇编代码转换为机器可以执行的指令。
  • 链接
    • 链接是一个复杂的过程,包括符号地址确定、符号解析与重定位、指令修正等。链接阶段有一项重要的工作,就是链接库文件,程序代码中经常会出现一些函数接口的使用,这些函数并不需要开发者自己实现,其功能已经被写好并编译到函数库中,开发者只需要调用库函数即可。
    • 函数库分为静态库与动态库两种。对静态库而言,编译链接时会把库文件代码加载到执行文件中,因此生成的文件体积较大,但运行时不需要库文件。动态库则刚好相反,在编译链接时并不会将库文件加载到执行文件,而是在程序执行时加载库文件。
选项 选项功能
-E 编译只执行预处理,不进行编译、汇编、链接处理
-S 编译执行生成汇编语言,不进行汇编、链接处理
-c 编译生成执行文件的依赖文件(.o文件)
-o 指定生成的新文件
-shared 此选项用来生成动态库时使用
-l 链接库文件时,指定库的名字
-L 链接库文件时,指定库所在的路径
-Wall 打开所有类型语法警告,建议经常使用
-w 禁止所有警告信息
-O、-O1 优化编译,减少目标文件的大小以及编译时间
-O2 包含-O1的优化,增加目标文件的执行性能

编译版本

GDB

GDB(GNU Symbolic Debugger)是GNU开源组织发布的一款程序调试工具。与Windows的IDE不同,GDB是纯命令执行,没有图形界面,但是其功能却比图形界面调试器更加强大。调试工作在产品研发中占有很重要的位置,一款产品从制定需求到成熟上线,可能需要做完成性测试,单元测试等,这些都离不开调试工具的使用。

GDB可以帮助用户完成查看程序的内部结构、查看自定义程序的启动方式、设置条件断点、单步调试源代码等各种调试工作。

# 编译生成调试信息
gcc -g test.c -o test
# 启动调试
gdb test
# 查看帮助命令
help
# 查看文件内容
list
# 设置断点
break [line]
# 查看断点
info break [n]
# 运行代码
r
# 查看变量
p [value]
# 单步运行
step/next [count]
# 继续执行
continue

MAKE

Make是一种工程管理器,其本质为管理多文件的一种工具。通常情况下,Make被用来编译源代码,其特点在于Make可以实现自动编译,所谓自动编译即根据文件的时间戳自动发现更新过的文件,以减少编译的工作量。通俗地说,即Make在编译代码时,只编译改动的文件,其他未改动且已经编译过的文件将不再编译,这大大缩短了编译的时间,提高了编译的效率。

Make工程管理器的核心文件为Makefile。Makefile中有3个关键的元素:目标(Target)、依赖(Dependency)、命令(Command)。

变量

类型 变量名 含义
预定义变量 ARFLAGS 库文件维护程序的选项,无默认值
-- ASFLAGS 汇编程序的选项,无默认值
-- CFLAGS C编译器的选项,无默认值
-- CPPFLAGS C预编译的选项,无默认值
-- CXXFLAGS C++编译器的选项,无默认值
自动变量 $* 不包括扩展名的目标文件名称
-- $+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件
-- $< 第一个依赖文件的名称
-- $? 所有时间戳比目标文件晚的依赖文件,并以空格分开
-- $@ 目标文件的完整名称
-- $^ 所有不重复的目标依赖文件,以空格分开

规则

  • 编译C程序隐含规则
    • 隐含规则:“xxx.o”的依赖会自动推导为“xxx.c”,并且其生成的命令为“$(CC) -c $(CPPFLAGS) $(CFLAGS)”。
  • 链接目标文件的隐含规则
    • 隐含规则:可执行文件“xxx”的依赖自动推导为“xxx.o”
  • VPATH
    • 大型项目工程中存在大量的源代码。这种情况下,开发者通常的做法是将这些源文件分类,并存放在不同的目录中。因此,Makefile中应该在文件的前面添加路径,当make执行时再找寻文件的依赖关系。特殊变量VPATH用于完成该功能,如果没有指定该变量,make只会在当前目录下寻找依赖文件和目标文件;而如果指定该变量,make在当前目录下找不到时,会到指定的目录中寻找文件

部署环境安装

安装软件一般有三种方式

  • rpm 相当于setup安装软件
  • 解压缩 相当于绿色安装
  • yum 相当于在线联网安装

JDK (rpm安装)

  1. 下载 IDK rpm。 去 oralce 官网下载即可!
  2. 安装java 环境
java -version 检测当前系统是否存在Java环境 和windows命令一样
#如果有的话就需要卸载
rpm -qa|grep jdk 查看JDK版本信息
rpm -e --nodeps jdk_xx 卸载
#卸载完毕后可安装JDK
rpm -ivh rpm包 
#开启防火墙端口
firewall-cmd --zone=public --add-port=9000/tcp --permanent
#重启防火墙
systemctl restart firewalld.service
#查看所有开启的端口,如果是阿里云 需要配置安全组规则
firewall-cmd --list-ports

Tomcat (gz解压缩安装)

ssm为war包需要在 tomcat 中运行

  1. 下载 tomcat 官网下载即可
  2. 解压 tar -zxvf apache-tomcat-9.0.36.tar.gz
  3. 启动 tomcat
#执行 
./startup.sh
#停止
./shutdown.sh
--zone #作用域  
--add-port-80/tcp #添加端口, 格式为: 端口 / 通讯协议  
--permanent #永久生效,没有此参数重启后失效
#开启对应防火墙端口
firewall-cmd --zone=public --add-port=8080/tcp –permanent

Docker(yum 安装)

  1. 检测 CentOS 7
cat /etc/redhat-release 
  1. 安装准备环境
#yum install 安装命令 -y  所有的提示都为y
yum -y install gcc gcc-c++
  1. 卸载以前的 docker
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
  1. 下载环境
yum install -y yum-utils \device-mapper-persistent-data \lvm2
  1. 使用国内阿里云镜像
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  1. 更新 yum 软件包安装
yum makecache fast
  1. 安装 docker ce
yum -y install docker-ce docker-ce-Cli containerd.io
  1. 启动 docker
systemctl start docker
  1. 测试
docker version
docker run hello-world
docker images

网络配置

网络基础知识

IP地址

IP地址是用于区分同一个网络中的不同主机的唯一标识。Internet中的主机要与其他机器通信必须具有一个IP地址,因为网络中传输的数据包必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由。IP地址可以为32位(IPV4,4个字节)或者128位(IPV6,16个字节)。通常使用点分十进制表示,例如:172.10.1.10。

IP地址由网络号和主机号两部分组成,其中网络号的位数直接决定可以分配的网络数,主机号的位数则决定网络中最大的主机数。由于整个互联网所包含的网络规模不太固定,因此IP地址空间被划分为不同的类别,每一类具有不同的网络号位数和主机号位数。

IP地址共分为5类,分别为A、B、C、D、E类。

  • A类IP地址,即在IP地址的4段号码中,第1段号码为网络号码,剩下的3段号码为本地计算机的号码。如果用二进制数表示IP地址,则A类IP地址就是由1字节的网络地址和3字节的主机地址组成。也就是说,A类IP地址中网络的标识长度为8位,主机标识的长度为24位。A类IP地址的范围为1.0.0.1 到 127.255.255.254(二进制表示为:00000001 00000000 00000000 00000001 ~ 01111111 11111111 11111111 11111110),最后一个地址为广播地址。因此A类网络数量较少,有126(2^7 -2)个网络,每个网络可以容纳主机数为16777214(2^24 -2)台。

  • B类IP地址,即在IP地址的4段号码中,前2段号码为网络号码。如果用二进制表示IP地址,则B类IP地址由2字节的网络地址和2字节主机地址组成,也就是说,B类IP地址中网络标识的长度为16位,主机标识的长度为16位。B类IP地址范围为128.0.0.1到191.255.255.254(二进制表示为10000000 00000000 00000000 00000001 ~ 10111111 11111111 11111111 11111110)。因此B类网络有16383(2^14 -1)个网络,每个网络可以容纳65534(2^16 -2)台主机。

  • C类IP地址,即在IP地址的4段号码中,前3段为网络号码,剩下的1段号码为本地计算机的号码。如果用二进制表示IP地址,则C类IP地址由3字节的网络地址和1字节的主机地址组成,也就是说,C类IP地址中网络的标识长度为24位,主机标识的长度为8位。C类IP地址范围为192.0.0.1到223.255.255.254(二进制表示为:11000000 00000000 00000000 00000001 ~ 11011111 11111111 11111111 11111110)。因此C类网络有2097152(2^21 -1)个网络,每个网络最多可容纳254(2^8 -2)台主机。

  • D类IP地址被称为多播地址或组播地址。组播地址被用来一次寻址一组计算机,即组播地址标识共享同一协议的一组计算机,其范围从224.0.0.0到239.255.255.255。

  • E类IP地址不分网络号和主机号,其范围为240.0.0.0到247.255.255.255。E类地址的第1个字节的前5为固定为11110。E类地址目前为保留状态,供以后使用。需要注意的是x.x.x.0与x.x.x.255不可以作为主机的IP地址,因为x.x.x.0用于表示一个网段,x.x.x.255用于广播地址。

子网掩码

子网掩码也可称为网络掩码。用户通过子网掩码可以很快确认当前主机IP所属的网络类型,通常网络地址部分为“1”,主机地址部分为“0”。 因此,A类IP地址的子网掩码为255.0.0.0;B类IP地址的子网掩码为255.255.0.0;C类IP地址的子网掩码为255.255.255.0。

子网掩码主要用于判断主机发送的数据包是发送给外网还是内网。主机A向主机B发送数据包,则主机A先将自己的子网掩码与目标主机B的IP地址执行“与”操作。假设主机B的IP地址为192.168.0.100,主机A的子网掩码为255.255.255.0,将IP地址与子网掩码进行“与”操作得到网络地址,结果为192.168.0.0。主机A将此网络地址与主机B所在的网络地址做对比:如果网络地址相同,则表明主机A与主机B在同一网络中,数据包向内网发送;如果不同,则向外网发送(发送至网关)。

网关

网关又称为连接器或协议转换器。主要用于在传输层上实现网络连接(两个上层协议不同的网络互联)。网关的实质是一个网络通向其他网络的IP地址。例如,网络A与网络B:网络A的IP地址范围为192.168.1.1~192.168.1.254,其子网掩码为255.255.255.0;网络B的IP地址范围为192.168.2.1~192.168.2.254,子网掩码为255.255.255.0。如果没有路由器,两个网络之间不能进行TCP/IP通信,因为TCP/IP协议根据子网掩码判定两个网络中的主机处于不同的网络,此时要实现网络间的通信,必须通过网关。这就如同在公司中同一个部门的员工可以直接相互交流,而不同部门的员工要当面聊天,则需要员工走出办公室出门,去其他办公室或会议室,此时的“门”就相当于网络中的网关。

如果网络A中的主机要向网络B中的主机发送数据包,则数据包需要先由主机转发给自己的网关,再由网关转发到网络B的网关,网络B的网关再将其转发给网络B的主机。

DNS服务器

DNS(Domain Name System,域名系统)是域名与IP地址相互映射的一个分布式数据库。其主要的目的是帮助用户更方便地访问互联网。例如,读者想了解千锋的相关信息时,需要在浏览器中输入千锋官方网站地址,这里输入的就是域名。想要成功进入网站,就必须设置DNS服务器,因为主机在与千锋服务器连接之前,必须通过域名服务器解析域名,从而得到千锋服务器的实际IP地址。这样做的好处在于,当用户需要通过网络访问某些服务时,不需要再去查找该服务的实际IP地址,使用固定的域名即可。

Linux网络配置

指令配置网络

  • 临时修改

    # 修改IP
    ifconfig eth0 [临时ip]
    # 修改物理地址,修改前禁用网卡
    ifconfig eth0 hw ether [物理地址]
    
  • 永久修改

    vim /etc/sysconfig/network-scripts/ifcfg-网络接口名称
    
    TYPE=Ethernet
    BOOTPROTO=static 		#(引导时不使用协议|静态分配|BOOTP协议|DHCP协议)
    DEFROUTE=yes
    IPV4_FAILURE_FATAL=no
    IPV6INIT=yes
    IPV6_AUTOCONF=yes
    IPV6_DEFROUTE=yes
    IPV6_FAILURE_FATAL=no
    NAME=eno16777736
    UUID=9e8d604f-d991-4aa2-88a3-4c679e6f139c
    DEVICE=eno16777736 物理设备名
    ONBOOT=yes 				# (引导时是否激活设备)
    PEERDNS=yes
    PEERROUTES=yes
    IPV6_PEERDNS=yes
    IPV6_PEERROUTES=yes
    HWADDR=00:0c:29:ce:3f:3c # MAC地址
    IPADDR=192.168.1.104     # 静态IP
    GATEWAY=192.168.1.2      # 默认网关
    NETMASK=255.255.255.0    #子网掩码
    DNS1=192.168.1.2         # DNS配置
    
    servicenetwork restart
    

常用网络服务

  • TFTP

    TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务;

    默认使用UDP 69端口;

    TFTP是一个传输文件的简单协议,它基于UDP协议而实现,但是我们也不能确定有些TFTP协议是基于其它传输协议完成的,此协议设计的时候是进行小文件传输的。

    它不具备通常的FTP的许多功能:

    • 它只能从文件服务器上获得或写入文件,不能列出目录,不进行认证;

    • 它传输8位数据;

    传输模式:

    • netascii:这是8位的ASCII码形式;

    • octet:这是8位源数据类型;

    • mail:已经不再支持,它将返回的数据直接返回给用户而不是保存为文件

    • 安装
    # tftp-server只是会依赖于xinetd.
    yum install -y xinetd tftp-server
    
    • 配置

      vim /etc/xinetd.d/tftp
      
      • 将disable的值更改为no,server_args添加-c

        tftp的默认根目录为/var/lib/tftpboot

        service tftp
        {
                socket_type             = dgram
                protocol                = udp
                wait                    = yes
                user                    = root
                server                  = /usr/sbin/in.tftpd
                server_args             = -s /var/lib/tftpboot -c # -c添加上传权限
                disable                 = no #默认为yes,这里我们将其更改为no
                per_source              = 11
                cps                     = 100 2
                flags                   = IPv4
        }
        
      • 默认目录添加权限

        chmod 777 /var/lib/tftpboot
        
    • 启动&使用

      systemctl restart xinetd
      
      TFTP [-i] host [GET | PUT] source [destination] 
      
  • NFS

    NFS是一种可以实现远程访问的文件系统,即NFS将系统中的文件通过网络共享给系统中的其他用户。这样用户就可以像访问本地文件一样访问远端系统上的文件

    • 安装服务端

      yum -y install nfs-utils rpcbind
      
    • 配置

      • 创建共享目录/export/nfs并设置权限

        mkdir -p /export/nfs
        chmod 666 /export/nfs/
        
      • 编辑export文件

        vim /etc/exports 
        /export/nfs 内网ip/24(rw,no_root_squash,no_all_squash,sync)
        
        参数值 内容说明
        rw / ro 该目录分享的权限是可擦写 (read-write) 或只读 (read-only),但最终能不能读写,还是与文件系统的 rwx 及身份有关。
        sync / async sync 代表数据会同步写入到内存与硬盘中,async 则代表数据会先暂存于内存当中,而非直接写入硬盘!
        no_root_squash  root_squash 客户端使用 NFS 文件系统的账号若为 root 时,系统该如何判断这个账号的身份?预设的情况下,客户端 root 的身份会由 root_squash 的设定压缩成 nfsnobody, 如此对服务器的系统会较有保障。但如果你想要开放客户端使用 root 身份来操作服务器的文件系统,那么这里就得要开 no_root_squash 才行!
        all_squash 不论登入 NFS 的使用者身份为何, 他的身份都会被压缩成为匿名用户,通常也就是 nobody(nfsnobody) 啦!
        anonuid / anongid anon 意指 anonymous (匿名者) 前面关于 *_squash 提到的匿名用户的 UID 设定值,通常为 nobody(nfsnobody),但是你可以自行设定这个 UID 的值!当然,这个 UID 必需要存在于你的 /etc/passwd 当中! anonuid 指的是 UID 而 anongid 则是群组的 GID 啰。
      • 刷新配置

        exportfs -r
        
    • 启动服务

      service rpcbind start
      service nfs start
      
    • 查看 RPC 服务的注册状况

      rpcinfo -p localhost
         program vers proto   port  service
          100000    4   tcp    111  portmapper
          100000    3   tcp    111  portmapper
          100000    2   tcp    111  portmapper
          100000    4   udp    111  portmapper
          100000    3   udp    111  portmapper
          100000    2   udp    111  portmapper
          100005    1   udp  49979  mountd
          100005    1   tcp  58393  mountd
          100005    2   udp  45516  mountd
          100005    2   tcp  37792  mountd
          100005    3   udp  32997  mountd
          100005    3   tcp  39937  mountd
          100003    2   tcp   2049  nfs
          100003    3   tcp   2049  nfs
          100003    4   tcp   2049  nfs
          100227    2   tcp   2049  nfs_acl
          100227    3   tcp   2049  nfs_acl
          100003    2   udp   2049  nfs
          100003    3   udp   2049  nfs
          100003    4   udp   2049  nfs
          100227    2   udp   2049  nfs_acl
          100227    3   udp   2049  nfs_acl
          100021    1   udp  51112  nlockmgr
          100021    3   udp  51112  nlockmgr
          100021    4   udp  51112  nlockmgr
          100021    1   tcp  43271  nlockmgr
          100021    3   tcp  43271  nlockmgr
          100021    4   tcp  43271  nlockmgr
      
      选项与参数:
      -p :针对某 IP (未写则预设为本机) 显示出所有的 port 与 porgram 的信息;
      -t :针对某主机的某支程序检查其 TCP 封包所在的软件版本;
      -u :针对某主机的某支程序检查其 UDP 封包所在的软件版本;
      
    • 查看共享目录

      showmount -e localhost
      Export list for localhost:
      /export/nfs 内网ip/24
      
      选项与参数:
      -a :显示目前主机与客户端的 NFS 联机分享的状态;
      -e :显示某部主机的 /etc/exports 所分享的目录数据。
      
    • 安装客户端

      yum -y install nfs-utils
      
    • 创建挂载目录

      mkdir /testnfs
      mount -t nfs 内网ip:/export/nfs /testnfs
      
    • 测试

      • 服务端

        [root@faetbwac testnfs]# echo "test" > test.txt
        
        [root@faetbwac testnfs]# cat /export/nfs/test.txt 
        test
        204
        
      • 客户端

        [root@faetbwac ~]# cat /testnfs/test.txt 
        test
        
        [root@faetbwac ~]# echo "204" >> /testnfs/test.txt 
        
    • 卸载nfs

      umount /testnfs
      df -h
      
      文件系统        容量  已用  可用 已用% 挂载点
      devtmpfs        909M     0  909M    0% /dev
      tmpfs           919M     0  919M    0% /dev/shm
      tmpfs           919M  508K  919M    1% /run
      tmpfs           919M     0  919M    0% /sys/fs/cgroup
      /dev/vda1        40G  2.3G   36G    6% /
      tmpfs           184M     0  184M    0% /run/user/0
      
  • SSH

    SSH(Secure Shell)是创建在应用层和传输层基础上的安全协议。相较于FTP、POP等传统的网络服务程序,SSH更为可靠,主要用于对远程登录的会话数据进行加密,有效防止远程管理过程中的信息泄露。

    • 安装

      yum install openssh-server
      
    • 命令

      # 查看ssh服务状态
      systemctl status sshd.service 
      # 重启ssh服务
      systemctl restart sshd.service 
      # 开启ssh服务
      systemctl start sshd.service 
      # 设置ssh服务开机自启
      systemctl enable sshd.service 
      

Shell

Shell是一种使用C语言编写的命令行解释器,被用来解析用户命令,实现用户与系统的交互。Shell命令则是用户向系统内核发送的的控制请求,这个控制请求是无法被内核理解的,只是一个文本流,需要解释器进行解释。而Shell脚本则是将命令、工具、编译过的二进制程序集合在一起的文件,同时可以内建命令,提供了数组、循环、条件以及判断等重要功能。开发者可以直接以Shell的语法来写程序,而不必使用类似C语言程序等传统程序的编写语法。

Shell脚本

脚本开头

符号“#!”为约定的标记,用来通知系统该脚本文件需要使用哪种类型的解释器来执行,即使用哪一种Shell。

#! /bin/bash

脚本执行

  • 增加执行权限

    chmod -X test.sh
    
  • 直接执行

    ./test.sh
    
  • 环境变量执行

    export PATH=/root/shell:$PATH
    test.sh
    
  • 解释器执行

    sh test.sh
    

变量

在Shell编程中,所有的变量都由字符串组成。不同于C语言程序中的变量,Shell脚本中的变量无须声明且没有数据类型。

Bourne Shell中有4种变量,分别为用户自定义变量、命令行参数、预定义变量、环境变量。

  • 用户自定义变量

    Shell脚本中的变量不支持数据类型(整型、字符型等),任何赋值给变量的值都被Shell解释为一串字符。

    变量的命名需要遵循以下规则

    • 只能使用字符、数字和下划线,首字符不能是数字。

    • 不能出现空格,可以使用下画线。

    • 不能使用Shell中已经定义的关键字。

    • 通常使用全大写,便于识别。

    注意,变量赋值等号两侧无空格

    #! /bin/bash
    
    NUM=1
    echo "${NUM}nd"
    
  • 命令行参数

    Shell编程中的命令行参数(位置参数)与C程序中的main函数传参类似。这些位置参数使用$N表示,N为正整数,表示命令行传入的第N个参数。N从0开始进行标记,与C语言中的数组表示的方式相同。例如,$1表示传递给脚本程序的第1个参数,并依此类推。$0表示程序本身的名字。

    #! /bin/sh
    
    VAR=$1
    echo "VAR = $VAR"
    
  • 预定义变量

    预定义变量即Shell已经定义的变量,用户可根据Shell的定义直接使用这些变量,无须自己定义。所有预定义的变量都由“$”和其他符号组成,常用的预定义变量如下所示。

    • $#:表示命令行参数的个数。

    • $@:包含所有的命令行参数,即“$1、$2、$3......”。

    • $?:前一个命令的退出状态,正常退出返回0,反之为非0值。

    • $*:包含所有的命令行参数,即“$1、$2、$3......”。

    • $$:正在执行的进程的ID号

    #! /bin/sh
    
    echo "$0"
    echo "$#"
    echo "$*" 
    
  • 环境变量

    环境变量是操作系统中具有特定名字的对象,Linux操作系统中的每一个用户都可以通过修改环境变量对自己的运行环境进行配置。

    环境变量按照生命周期的不同可以分为永久性环境变量和临时性环境变量。根据用户等级的不同可以分为系统级环境变量和用户级环境变量。

    • 临时环境变量

      • 临时环境变量只对当前的Shell有效,如果用户退出登录或终端关闭,则环境变量失效。
    • 永久性环境变量(系统级)

      • 系统级的永久性环境变量对系统内所有的用户生效,其作用范围为整个系统。
      • 用户在系统配置文件“/etc/profile”中添加需要的环境变量后,使用source命令刷新配置,即可使该变量生效。
    • 永久性环境变量(用户级)

      • 用户级的永久性环境变量只对当前用户有效。某一个用户设置此类环境变量后,该变量对于其他用户来说是不存在的。

      • 设置此类环境变量需要配置用户主目录下的隐藏文件“.bashrc”。设置的方法与上一步部分中设置系统级变量时一致。

    环境变量 含义
    HOME 表示用户主目录
    PATH Shell 的搜索路径
    TERM 终端的类型
    HISTSIZE 历史命令记录的条数
    OGNAME 当前用户登录名
    IOSTNAME 主机名称
    SHELL 当前用户使用的 Shell 的类型
    TMOUT 被用来设置Shell脚本过期的时间
    UID 已登录用户的ID
    USER 当前用户的名字
    使用方式 功能
    echo 显示指定环境变量
    export 导出新的环境变量
    env 显示系统所有的环境变量
    set 显示本地定义的环境变量
    unset 清除环境变量设置

语句

Shell语句在一个完整的Shell程序中有着十分重要的作用。使用Shell语句不仅可以实现功能性的设计,而且可以连接控制命令。Shell语句可以分为3类:说明性语句、功能性语句、结构性语句。

  • 说明性语句

    说明性语句指的是注释行。注释行可以出现在Shell程序的任何位置,既可以单独一行,也可以出现在执行语句的后面。Shell程序中使用符号#注释语句,表示该语句不被解释执行。

  • 功能性语句

    在Shell程序中,变量除了可以直接被赋值以外,还可以从程序外部获取值。外部获取变量的值使用键盘输入即可。

    • 键盘读取变量值

      # read [变量]
      #! /bin/sh
      
      echo "Please input name of directory:"
      read DIRECTORY          #读取终端输入,保存该值到变量DIRECTORY中
      
      ls $DIRECTORY -l        #查询变量所指的目录中文件的信息
      
    • 算术运算

      在Shell中,算术运算指令expr可用于实现简单的算术运算。如加(+)、减(-)、乘(*)、除(/)、取余(%)等操作。其表达式格式如下所示,注意符号“`”为反引号,物理键位于键盘中Esc键下方。

      注意,算术运算符在使用时必须搭配expr指令,单独使用没有任何效果。

      注意,expr命令在配合算术运算符使用时,运算符两边必须有空格。

      #! /bin/sh
      
      echo "Please input numbers:"
      
      #读取键盘输入的值,保存到变量VAR1/VAR2中
      read VAR1
      read VAR2
      
      #使用算数运算符进行计算
      ADD=`expr $VAR1 + $VAR2`    #和
      SUB=`expr $VAR1 - $VAR2`    #差
      MUL=`expr $VAR1 \* $VAR2`   #乘
      DIV=`expr $VAR1 / $VAR2`    #除
      MOD=`expr $VAR1 % $VAR2`    #取余
      	
      echo "$VAR1+$VAR2 = $ADD"
      echo "$VAR1-$VAR2 = $SUB"
      echo "$VAR1*$VAR2 = $MUL"
      echo "$VAR1/$VAR2 = $DIV"
      echo "$VAR1%$VAR2 = $MOD"  
      
    • test命令

      Shell中的test命令用来测试某个条件是否成立,其测试的对象主要为字符串、整数、文件属性。每种测试对象都有一套具体的测试操作符,Shell程序通过这些测试操作符,来完成具体的测试需求。

      注意,“[”后和“]”前以及“=”两端都有空格,且不可省略。

      字符串测试 含义
      s1 = s2 测试两个字符串内容是否一致
      s1 != s2 测试两个字符串内容是否有差异
      -z s1 测试字符串s1的长度是否为О
      -n s1 测试字符串s1的长度是否不为О
      #! /bin/sh
      
      read VAR1         #读取输入字符串保存至变量
      read VAR2
      
      [ "$VAR1" = "$VAR2" ]   #判断字符串是否相等
      
      echo $?         #输出前一个命令的返回码
      
      整数测试 含义
      a -eq b 测试a 与b是否相等
      a -ne b 测试a 与b是否不相等
      a -gt b 测试a是否大于b
      a -ge b 测试a是否大于等于b
      a -lt b 测试a是否小于b
      a -le b 测试a是否小于等于b
      #! /bin/sh
      
      read VAR1
      read VAR2
      
      test $VAR1 -eq $VAR2       #判断输入的整数是否相等
                                                                                  
      echo $?             #返回上一条命令的状态值,即相等为0.不相等为非0
      
      文件测试 含义
      -d filename 测试filename是否为目录
      -f filename 测试filename是否为普通文件
      -L filename 测试filename是否为符号链接
      -r filename 测试filename是否存在且为可读
      -w filename 测试filename是否存在且为可写
      -x filename 测试filename是否存在且为可执行
      -s filename 测试filename是否存在且长度不为0
      filename1 -nt filename2 测试fi1ename1是否比 filename2新
      #! /bin/sh
      
      read VAR             #读取终端输入的字符串保存到变量VAR中
      test -d $VAR        #测试文件是否为目录
      
      echo $?
      
  • 结构性语句

    • 条件判断

      if与fi必须成对使用,表示条件语句的语句括号;命令表中的命令可以是一条,也可以是若干条。

      if 表达式
      then 命令表
      else 命令表
      fi
      
      #! /bin/sh
      
      read VAR
      if [ -d $VAR ]             #判断文件是否为目录
      then 
      	ls $VAR –l              #判断条件为真,则查看目录中文件的信息
      else
      	if [ -f $VAR ]         #判断文件是否为普通文件
      then 
      	cat $VAR            #判断条件为真,则查看文件中的内容
      	fi                                                            
      fi
      
    • 多路分支

      case 字符串变量 in
      	模式1)
      		命令表1
      		;;
      	...
      	模式n)
      		命令表n
      		;;
      esac
      
      #! /bin/sh
      
      case "$1" in
      	"start")
      		echo "服务开启..."
      		;;
      	"stop")
      		echo "服务关闭..."
      		;;
      	"restart")
      		echo "服务重启..."
      		;;
      	*)
      		echo "输入提示:$0 + [start/stop/restart]"
      		;;
      esac
      
    • for循环

      for 变量 in 单词表
      do
      	命令表
      done
      
      #! /bin/sh
      
      ADD=0
      i=0
      while [ $i -le 100 ]          #判断变量i小于等于100时条件为真
      do
      	ADD=`expr $ADD + $i`      #累加
      	i=`expr $i + 1`            #变量i+1
      done
      echo $ADD    
      
    • while循环

      while 命令或表达式
      do
      	命令表
      done
      
      #! /bin/sh
      
      for i in `seq 1 6`
      do
      	if [ $i -eq 3 ]             #判断变量i是否等于3 
      	then
      		continue                 #如果判断条件为真,则跳过本次循环
      	fi
      echo $i
      done
      
    • 循环控制

      循环控制语句包括break语句与continue语句。break语句表示跳出整个循环,而continue语句只是跳出本轮循环,进入下一轮循环。

      #! /bin/sh
      
      for i in `seq 1 6`
      do
      	if [ $i -eq 3 ]             #判断变量i是否等于3 
      	then
      		continue                 #如果判断条件为真,则跳过本次循环
      	fi
      echo $i
      done
      

函数

在实际的程序编程中,开发者通常将具有固定功能且多次使用的一组命令(语句)封装在一个函数中,当需要使用该功能时只需调用该函数即可。在Shell中同样可以使用函数,需要注意的是,函数在调用前必须先定义。

调用程序可以传递参数给函数,函数可用return语句将运行后的结果返回给调用程序。

  • 函数定义

    func_name()
    {
    	command
    }
    
    func func_name()
    {
    	command
    }
    
  • 函数调用

    value=`func_name[args ...]`
    
    func_name[args ...]
    
  • 函数使用

    #! /bin/sh
    
    add()
    {
    a=$1
    b=$2
    c=`expr $1 + $2`
    echo "The sum is $c"
    }
    
    add $1 $2       #调用函数
    

脚本调用

#! /bin/sh

echo "test18.sh"
./test14.sh
echo "end of run"

应用

#!/bin/bash

# 脚本生成一个 100 以内的随机数,提示用户猜数字,根据用户的输入,提示用户猜对了,
# 猜小了或猜大了,直至用户猜对脚本结束。

# RANDOM 为系统自带的系统变量,值为 0‐32767的随机数
# 使用取余算法将随机数变为 1‐100 的随机数
num=$[RANDOM%100+1]

# 使用 read 提示用户猜数字
# 使用 if
# 判断用户猜数字的大小关系:‐eq(等于),‐ne(不等于),‐gt(大于),‐ge(大于等于),
# ‐lt(小于),‐le(小于等于)
count=0

while  :
do
	read -p "计算机生成了一个 1‐100 的随机数,你猜: " guess
	if [ $guess -eq $num ]
	then
		echo "恭喜,竞猜正确"
		exit
	elif [ $guess -gt $num ]
	then
		echo "猜大"
	elif [ $guess -lt $num ]
	then
		echo "猜小"
	fi

	(( count ++ ))

	if [ $count -lt 7 ]
	then
		continue
	else
		echo "竞猜失败"
		break
	fi 
done


#!/bin/bash
# 编写脚本,实现人机<石头,剪刀,布>游戏
game=(石头 剪刀 布)  #定义一个数组,数组元素为石头、剪刀、布
num=$[RANDOM%3]  #取余后,num的值只能为0/1/2

com=${game[$num]}  #读取数组中元素的值,保存至变量com中
# 目的是表明game数组使用num作为下标
# 通过随机数获取计算机的出拳
# 出拳的可能性保存在一个数组中,game[0]、game[1]、game[2]分别是石头、剪刀、布

echo "请根据以下提示选择出拳手势"
echo "1.石头 2.剪刀 3.布"

#直接判断用户输入与数组下标即可
read -p "请选择 1~3: " user
case  $user  in
	1)                              #如果user变量的值为1,表示玩家出石头
		if [ $num -eq 0 ]
		then
			echo "平局"
		elif [ $num -eq 1 ]
		then
			echo "玩家赢"
		else
			echo "计算机赢"
		fi;;
	2)                             #如果user变量的值为2,表示玩家出剪刀
		if [ $num -eq 0 ]
		then
			echo "计算机赢"
		elif [ $num -eq 1 ]
		then
			echo "平局"
		else
			echo "玩家赢"
		fi;;
	3)                          #如果user变量的值为3,表示玩家出布
		if [ $num -eq 0 ]
		then
			echo "玩家赢"
		elif [ $num -eq 1 ]
		then
			echo "计算机赢"
		else
			echo "平局"
		fi;;
	*)
		echo
		"请输入1‐3的数字"
esac

正则表达式

​ 正则表达式由一些普通字符和元字符组成。普通字符包括大小写字母和数字,元字符则有一些特殊的含义。这些特定的字符组成一个“规则字符串”,用来表示对其它字符串的一种过滤逻辑。

符号定义与匹配规则

linux中grep支持正则表达式

元字符

元字符 功能说明
. 匹配任何字符(换行符除外)
\w 匹配字母或数字或下划线或汉字
\b 匹配单词的开始或结尾
\s 匹配任意空白符
\d 匹配数字
^ 匹配行首
$ 匹配行尾
\f 匹配一个换页符
\n 匹配一个换行符
\r 匹配一个回车符

反义字符

反义字符 功能说明
\W 匹配任意不是字母、数字、下划线、汉字的字符
\B 匹配不是单词开头或结束的位置
\s 匹配任意不是空白符的字符
\D 匹配任意不是数字的字符
[^X] 匹配任意不是x的字符
[^XY] 匹配任意不是x且不是y 的字符

重复使用

注意,在Shell中“{}”具有特殊意义,因此在“{”与“}”前需要使用转义字符“\”,使其失去特殊意义。

符号 功能含义
* 重复零次或更多次
? 重复零次或一次
+ 重复一次或更多次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

字符簇

字符簇 功能含义
[a-z] 匹配小写字母
[A-Z] 匹配大写字母
[a-zA-Z] 匹配所有字母
[0-9] 匹配所有数字
[-] 匹配连接符

文本处理工具

sed

sed本身是一个管道命令,可以被用来分析标准输入,实现数据的替换、删除、增加、选取等功能。

sed [-选项] 操作
选项 功能
-n 使用安静模式,表示在终端上只显示经过sed特殊处理的一行信息
-e 直接在命令行模式进行sed的操作编辑
-f 指定文件,执行文件中的sed操作
-r sed操作使用扩展型正则表达式语法
-i 直接修改读取的文件内容,不输出结果
# 操作文本
sed n1,n2 function
操作 说明
a 新增,在指定行的下一行新增字符
c 替换,替换n1到n2行之间的内容
d 删除,删除指定行
i 插入,在指定行的上一行插入字符
p 打印,通常与sed选项-n一同使用,将选择的数据输出
s 替换

awk

awk是一个非常好的数据处理工具,相较于sed命令的整行处理,awk命令更倾向于对一行中的某些字段进行处理。awk工具非常适合处理小型的文本。

awk '条件类型1{操作1} 条件类型2{操作2} ...' filename
  • 内置变量
变量 描述
$n 当前记录的第n个字段
$o 完整的记录
FS 分隔符,默认是空格,可设置为其他
NF 每一条记录的字段数目
NR 已经读出的记录数(当前所处的行数)
FILENAME 当前文件名
  • 运算逻辑符
运算符 含义
> 大于
< 小于
>= 大于或等于
<= 小于或等于
== 等于
!= 不等于
  • BEGIN/END模式

    特殊模式BEGIN用于匹配第一个输入文件的第一行之前的位置,END则用于匹配处理过的最后一个文件的最后一行之后的位置

参考链接

推荐阅读