前言

发烧了2天,掉了一天的水,烧的快见太奶了。

Last,纵使人生百般滋味,也要笑对!!!

Linux背景介绍

Linux版本

1
2
3
内核版本:

https://www.kernel.org

内核版本分为三个部分,主版本号、次版本号、末版本号,次版本号是奇数为开发板,偶数为稳定版

发行版本

RedHat:经过专业测试

Fedora:社区发行,版本较新,但是没有经过专业测试。(也是redhat发行)

CentOS:用RedHat的源代码编译,但是把RedHat的商标等去掉。但是没有一些技术支持

桌面安装:Debian,Ubuntu

常见目录

1
2
3
4
5
6
7
/  根目录
/root root用户的家目录
/home/username 普通用户的家目录
/etc 配置文件目录
/bin 命令目录
/sbin 管理命令目录
/usr/bin/usr/sbin 系统预装的其他命令

sbin和bin命令的区别

sbinbin都是Linux文件系统中的重要目录,它们分别存放了系统的重要可执行文件。这两个目录的主要区别在于,它们各自存放的命令的使用者不同。

  • bin目录:这个目录存放的是所有用户都可以运行的命令。这些命令包括很多基本的Linux命令,如ls、cp、rm等。bin是“binary”的缩写,意为二进制,表示这个目录下存放的都是可执行的二进制文件。
  • sbin目录:这个目录存放的是系统管理员(root用户)才能运行的命令。这些命令一般都是和系统管理有关的,如fdisk、ifconfig等。sbin是“system binary”的缩写,表示这个目录下存放的都是系统命令的二进制文件。

总的来说,binsbin的区别在于,bin目录下的命令是给所有用户使用的,而sbin目录下的命令则是给系统管理员使用的。

另外,除了根目录下的/bin/sbin,在/usr目录下也有/usr/bin/usr/sbin两个目录。它们的作用和根目录下的/bin/sbin类似,只不过/usr/bin/usr/sbin中的命令是非必需的,也就是说,系统可以在没有这些命令的情况下正常运行。

系统操作

帮助命令

1
2
3
4
5
man 是 manual 的缩写
man 帮助用法演示
#man ls
man 也是一条命令,分为9章,可以使用man命令获得man的帮助
#man 7 man

man命令

man 1 killman 2 kill,这些命令都是查看 kill 命令的手册,但是文档却大不相同。

因为 kill 是一个命令行的工具,which kill 看到 /usr/bin/kill 是一个二进制文件;其实,也有一个系统调用叫做 kill。

man 1 kill 显示的是命令行工具 kill 的手册;

man 2 kill 显示系统调用 kill 的手册;

显示什么类型的手册,由 man 和命令中间的数字决定,目前共有 9 个 man 支持的数字。

数字 说明
1 可执行程序或 Shell 命令
2 系统调用(内核提供的函数)
3 库调用
4 特殊文件(通常位于 /dev 目录)
5 文件格式和约定(比如 /etc/passwd)
6 游戏
7 杂项(包和一些约定)Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)
8 系统管理命令(通常是 root 用户执行的命令)
9 内核相关的文件 Kernel routines [Non standard]
1
2
3
4
5
6
7
8
9
10
help
shell(命令解释器)自带的命令成为内部命令,其他的是外部命令
内部命令使用 help 帮助
#help cd
外部命令使用help帮助
#ls --help

可以通过type来判断一个命令是内部还是外部命令
#type ls
#type cd

Linux的命令可以分为内部命令和外部命令:

  • 内置命令在系统启动时就调入内存,是常驻内存的,所以执行效率高。
  • 外部命令是系统的软件功能,用户需要时才从硬盘中读入内存。

文件管理

显示当前的目录

1
pwd 显示当前的目录名称

更改当前的操作目录

1
2
3
4
5
cd 更改当前的操作目录

cd /path/to/... 绝对路径
cd ./path/to/... 相对路径
cd ../path/to/... 相对路径

文件查看

1
2
3
4
5
6
7
8
ls 查看当前目录下的文件
ls / /root 这样会同时查看根目录和 /root目录下的文件
常用参数
-l 长格式显示文件
-a 显示隐藏文件
-r 逆序显示(默认按照文件名排序)
-t 按照时间顺序显示 ls -l -r -t (会按照时间逆向排序)
-R 递归显示 -h 人性化显示、 -d 只显示目录
1
2
3
4
5
6
7
8
(base) sv@sv-NF5280M5:/$ sudo ls /  /root
[sudo] sv 的密码:
/:
bin cdrom data_old etc lib lib64 lost+found mmkv.default mnt proc run snap swapfile tmp var
boot data dev home lib32 libx32 media mmkv.default.crc opt root sbin srv sys usr

/root:
snap

目录文件的创建与删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mkdir  建立空目录
mkdir a

常用参数
-p 递归创建多级文件夹

rmdir 删除空文件夹
rmdir a

rm 可以删除非空目录及文件

常用参数
-r 删除目录
-f 强制删除,不提示
需要注意,rm -rf 后面可以跟多个目录,不要出现 rm -rf / usr 这种,会从根目录开始删除

复制和移动目录

1
2
3
4
5
6
7
8
cp 复制文件和目录
cp /root/a /tmp(临时文件)

常用参数
-r/R 递归复制目录
-v 显示过程
-p 保留文件原有更新时间(属性)
-a 时间戳+所有权+复制连接文件属性而非档案本身 -f 强行覆盖 -i 覆盖之前先行提示
1
2
3
4
5
6
7
mv 移动文件或者重命名
mv /a /othera
mv /a /tmp
mv /a /tmp/b(移动+重命名)

常用参数
-i 覆盖文件前提示

通配符

1
2
3
4
5
6
7
8
定义:shell 内建的符号
用途:操作多个相似(有简单规律的)文件
常用通配符:
  * 匹配任何字符串
  ? 匹配1个字符串
  [xyz] 匹配xyz任意一个字符
  [a-z] 匹配一个范围
  [!xyz]或者[^xyz] 不匹配

文本内容查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cat 文本内容显示到终端
显示全部
head 查看文件开头
head test.txt 默认查看前10行
head -5 test.txt

tail 查看文件结尾
tail -1000f catalina.out
常用参数
-f 文件内容更新后,显示信息同步更新

wc 统计文件内容信息
wc -l /tmp/test.txt 查看文件有多少行
-c或--bytes或——chars:只显示Bytes数;
-l或——lines:只显示列数;
-w或——words:只显示字数。
more 分行显示
less

Note:可以使用tail -f 查看日志内容。

打包和压缩

1
2
3
4
5
6
7
8
9
10
最早的Linux备份介质是磁带,使用的命令是tar
可以打包后的磁带文件进行压缩储存,压缩的命令是 gzip 和 bzip2
经常使用的扩展名是 .tar.gz .tar.bz2 .tgz
tar 打包命令
常用参数
c 打包
x 解包
f 指定操作类型为文件    v 显示进度 P 使用绝对路径
打包
tar cf /tmp/etc-backup.tar /etc/etc 这个文件夹打包放在/tmp/etc-backup.tar会提示,但是也能成功:tar: Removing leading `/' from member names
1
2
3
4
5
6
7
8
tar cPf /tmp/etc-backup.tar /etc      使用绝对路径 (没有提示)
tar czf /tmp/etc-backup.tar.gz /etc (tar集成了gzip和bzip2)
tar cjf /tmp/etc-backup.tar.bz2 /etc (压缩比例更高)

解包
tar xf /tmp/etc-backup.tar -C /root 把 tar包解压到 /root 目录下
tar zxf /tmp/etc-backup.tar.gz -C /etc
tar zjf /tmp/etc-backup.tar.gz -C /etc

VI

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
多模式产生的原因
四种模式:
正常模式(Normal-mode)
插入模式(Insert-mode)
命令模式(Command-mode)
可视模式(Visual-mode)

i 进入插入模式
i是当前光标
I是光标当行开头
a是光标后一位
A是光标当行结尾
o下一行,会产生一个空行
O上一行,会产生一个空行

v进入可视模式

:进入命令模式

esc返回正常模式

正常模式下:
hjkl可以控制上下左右

yy表示复制当行,p可以粘贴
3yy表示复制三行
y$ 表示复制从光标到当行结尾
dd d$表示剪切

操作错误,u可以撤销,ctrl+r重做
x表示删除当前光标的字符
r可以替换当前字符

:set nu 可以查看目前是第几行
数字 + G可以到数字对应的行
g移动到第一行
G移动到最后一行


^来到光标所在行的开头,$来到光标所在行的结尾


命令模式
:w /root/test.txt 文件新建的,可以保存一个新文件
:w 文件已经存在的情况下,保存
:wq 保存退出
:q! 强制退出

:! 执行linux命令,看完后回车重新回到vim
/x 查找x字符,n查找下一个,shift+n上一个
:s/old/new 用新字符替换旧字符(只正对光标所在的行)
:%s/old/new 用新字符替换旧字符(整个文本,但只替换一个)
:%s/old/new/g 用新字符替换旧字符(整个文本,全部替换)
:3,5s/x/X/g 3-5行内全部替换,替换一个就去掉g

:set nu 显示行号
:set nonu 不显示行号

以上是单次修改的,如果要修改默认配置
vim /etc/vimrc


可视模式
三种进入可视模式的方式
v 字符可视模式
V 行可视模式
ctrl + v 块可视模式
配合d和I(大写i)命令可以进行块的便利操作

需要在块的所有行之前加入一些字符,选中块,I的时候会在选中的块的第一行的第一个光标处,输入字符,连续两次esc。
选中块,d,然后选中的块就会被删除

用户与权限管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
useradd 新建用户
useradd dongye(可以用 id dongye 来验证是否存在)
创建一个用户后,自动在 /home建立家目录,并且创建一些隐藏文件。同时,在 /etc/passwd 这个文件里会加入新用户dongye的数据,/etc/shadow里面也有会相关数据(密码相关)。如果没有组的话,创建一个同名的组。
userdel 删除用户
userdel dongye
userdel -r dongye 同时删除家目录
passwd 修改用户密码
passwd dongye
passwd更改当前用户密码
/etc/passwd 和 /etc/shadow 里面的数据也被删除
usermod 修改一个用户账户
usermod -d /home/other dongye 家目录从 /home/dongye 改成 /home/other
chage 修改用户生命周期 设置用户密码的过期时间,甚至用户本身的过期时间

奇怪的现象

1
2
3
root@penge-virtual-machine:/home# useradd test
root@penge-virtual-machine:/home# ls
penge

GPT解答

在Linux中,当你创建一个新的用户时,系统会默认在 /home 目录下创建一个与用户名同名的家目录。你可以使用 useradd 命令来创建新用户。下面是一些示例:

  • 创建一个新用户并指定家目录:
1
useradd -m username

这里的 -m 选项表示创建家目录。

  • 如果你想指定家目录的路径,你可以使用 -d 选项:
1
useradd -m -d /home/custom_directory username

这里,-d 选项后面跟的是你想要设定的家目录的路径。

  • 记得,创建新用户后,你需要为新用户设置密码,这样新用户才能登录。你可以使用 passwd 命令来设置密码:
1
passwd username

不过请注意,这些操作需要管理员权限,所以在命令前可能需要加上 sudo

如果你已经创建了用户但忘记了设置家目录,你可以使用 usermod 命令来修改用户的家目录:

1
usermod -d /home/new_directory username

这里,-d 选项后面跟的是你想要设定的新的家目录的路径。

使用/etc/passwd查看

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
root@penge-virtual-machine:/home# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:115::/nonexistent:/usr/sbin/nologin
avahi-autoipd:x:109:116:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
usbmux:x:110:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
rtkit:x:111:117:RealtimeKit,,,:/proc:/usr/sbin/nologin
dnsmasq:x:112:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
cups-pk-helper:x:113:120:user for cups-pk-helper service,,,:/home/cups-pk-helper:/usr/sbin/nologin
speech-dispatcher:x:114:29:Speech Dispatcher,,,:/run/speech-dispatcher:/bin/false
avahi:x:115:121:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologin
kernoops:x:116:65534:Kernel Oops Tracking Daemon,,,:/:/usr/sbin/nologin
saned:x:117:123::/var/lib/saned:/usr/sbin/nologin
nm-openvpn:x:118:124:NetworkManager OpenVPN,,,:/var/lib/openvpn/chroot:/usr/sbin/nologin
hplip:x:119:7:HPLIP system user,,,:/run/hplip:/bin/false
whoopsie:x:120:125::/nonexistent:/bin/false
colord:x:121:126:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
geoclue:x:122:127::/var/lib/geoclue:/usr/sbin/nologin
pulse:x:123:128:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
gnome-initial-setup:x:124:65534::/run/gnome-initial-setup/:/bin/false
gdm:x:125:130:Gnome Display Manager:/var/lib/gdm3:/bin/false
sssd:x:126:131:SSSD system user,,,:/var/lib/sss:/usr/sbin/nologin
penge:x:1000:1000:penge,,,:/home/penge:/usr/bin/zsh
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
sshd:x:127:65534::/run/sshd:/usr/sbin/nologin
fwupd-refresh:x:128:135:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
mysql:x:129:137:MySQL Server,,,:/nonexistent:/bin/false
test:x:1001:1002::/home/test:/bin/sh

id test

1
2
root@penge-virtual-machine:/home# id test
uid=1001(test) gid=1002(test) groups=1002(test)
1
id [-gGnru][--help][--version][用户名称]

参数说明

  • -g 或 --group  显示用户所属群组的ID。
  • -G 或 --groups  显示用户所属附加群组的ID。
  • -n 或 --name  显示用户,所属群组或附加群组的名称。
  • -r 或 --real  显示实际ID。
  • -u 或 --user  显示用户ID。
  • -help  显示帮助。
  • -version  显示版本信息。

组管理命令

1
2
3
4
5
6
groupadd 新建用户组
groupadd group1
useradd user1
usermod -g group1 user1 把user1这个用户的组改成group1
useradd -g group1 user2 新建用户user2时就把它放到group1组下
groupdel 删除用户组 groupdel group1 删除组group1

用户切换

1
2
3
4
5
6
su 切换用户
su - USERNAME 使用 login shell 方式切换用户
su USERNAME 不完全切换,比如还是在 /root下而不会自动跳转到用户家目录

sudo 以其他用户身份执行命令
visudo 设置需要使用sudo的用户(组)。下图设置 user3用户拥有shutdown -c权限,需要输入 user3自己的密码

su和sudo的区别

susudo都是Linux系统中用于权限管理的命令,它们的主要区别在于使用方式和权限控制:

  • su命令:su是“Switch User”的缩写,主要用于切换到其他用户。当你输入su命令后,系统会提示你输入目标用户的密码,输入正确后,你就切换到了那个用户,拥有了那个用户的全部权限。如果没有指定用户名,那么默认切换到root用户。
  • sudo命令:sudo是“Super User DO”的缩写,主要用于临时获取root权限。当你在命令前加上sudo后,那个命令就会以root用户的身份运行,但之后的操作还是以普通用户的身份进行。使用sudo需要输入当前用户的密码,并且当前用户需要在sudoers文件中(一般位于/etc/sudoers)。

总的来说,su是切换到其他用户,拥有目标用户的全部权限;而sudo则是临时获取root权限,执行完命令后仍然保持原用户身份。使用哪个命令主要取决于你的需求,如果你需要连续执行多条需要root权限的命令,可能使用su切换到root用户会更方便;如果你只是临时需要执行一条需要root权限的命令,那么使用sudo可能更安全,更符合权限最小化的原则。

用户和用户组的配置文件介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/etc/passwd 用户配置文件,7个字段

user3:x:1003:1003::/home/user3:bin/bash
user3:用户名称
x:是否需要密码验证,x表示需要,空表示不需要
1003:用户的uid,用户的id信息,唯一识别用户的标识。root是0。
1003:用户的gid,表示组id信息
第五个字段:注释
/home/user3:家目录
/bin/bash:用户登录后的命令解释器。/sbin/nologin 表示不能登录

/etc/shadow 保存用户和用户密码相关信息的
第一个字段:用户名称
第二个字段:用户加密过后的密码(看到也没用,经过处理,即使相同的密码也会显示不同)

/etc/group 用户组相关的配置文件,4个字段
group:x:10:another
group:组的名称
x:是否需要密码验证
10:gid
another:其他组设置,说明another这个用户的第二个组是group比如输入 id user1uid=1001(user1) gid=1001(group1) 组=1001(group1)id anotheruid=1002(another) gid=1002(another) 组=1003(group) 查找another信息,发现他的第二个组是group

文件与目录权限表示方法

image-20240509110036508

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
33
文件类型
- 普通文件
d 目录文件
b 块特殊文件
c 字符特殊文件
l 符号链接
f 命名管道
s 套接字文件


文件权限的表示方法

字符权限表示方法
r 读
w 写
x 执行

数字权限的表示方法
r=4
w=2
x=1

文件权限的表示方法
rwxrwxrwx
第一个表示文件属主的权限,第二个表示文件属组的权限,第三个表示其他用户的权限

创建新文件有默认权限,根据umask值计算,属主和属组根据当前进程的用户来设定


目录权限的标识方法
x 进入目录
rx 显示目录内的文件名
wx 修改目录内的文件名

文件权限的修改方法和数字表示方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
修改权限命令(测试的时候别用root,root不受限制)

chmod 修改文件、目录权限
chmod u+x /tmp/testfile u表示属主
chmod u=rwx /tmp/testfile
chmod g-r /tmp/testfile g表示属组
chmod 0-r /tmp/testfile o表示其他用户
chmod a+r /tmp/testfile a表示所有
chmod 755 /tmp/testfile如果属主没有权限,所属的组有权限,以属主为准,还是没有权限。
chown 更改属主、属组
chown user1 /test 把test这个目录的属主改成user1
chown :group /test 把test这个目录的属组给成group chown user1:group /test 一起修改
chgrp 可以单独更改属组、不常用

linux一般创建一个文件默认会赋予666权限,然后根据用的umask值来计算。
用户默认umask值为022,所以一般是 666-022=644,对应rw-r--r--

特殊权限

1
2
3
4
5
6
7
SUID  用于二进制可执行文件,执行命令时取得文件属主权限
如,/usr/bin/passwd

SGID 用于目录,在该目录下创建新的文件和目录,权限自动更改为该目录的属组
文件共享时使用
SBIT 用于目录,该目录下新建的文件和目录,仅root和自己可以删除
如 /tmp

网络管理

网卡介绍

网卡,也被称为网络接口卡(Network Interface Card,NIC),是一种硬件设备,它允许计算机通过网络与其他计算机进行连接和通信。一般来说,网卡被安装在计算机或其他网络设备的扩展插槽中。

网卡的主要工作是将数据包发送和接收到网络上。它把计算机中的数字信息转化为可以在网络上传输的信号,同时也能把网络上的信号转化为计算机可以理解的数字信息。这个过程被称为“调制”和“解调”。

每个网卡都有一个全球唯一的物理地址,也叫作MAC地址。这个地址在网卡生产时被厂家写入,用于在网络上唯一标识这个网卡。

网卡可以按照连接方式分类,有有线网卡和无线网卡两种。有线网卡一般使用以太网线缆(Ethernet Cable)进行连接,而无线网卡则使用无线信号,如Wi-Fi进行连接。

网络状态查看

1
2
3
4
5
6
7
8
9
10
net-tools VS iproute

1. net-tools
ifconfig
route
netstat

2. iproute2
ip
ss

网卡名称

1
2
3
4
5
6
7
ifconfig查看网卡名称
· eth0 第一块网卡(网络接口)
· 你的第一个网络接口可能叫做下面的名字
· eno1 板载网卡
· ens33 PCI-E网卡
· enp0s3 无法获取物理信息的 PCI-E 网卡
· CentOS7使用了一致性网络设备命名,以上都不匹配则使用eth0

PCI-E网卡:

PCI-E网卡是一种使用PCI Express接口的网络适配器,它是计算机硬件的重要组成部分,负责处理计算机的网络连接。以下是关于PCI-E网卡的一些重点介绍:

  1. 高速性能:PCI Express接口(也被称为PCI-E或PCIe)是一种高速硬件接口,它提供了比传统的PCI接口更快的数据传输速率。这使得PCI-E网卡在处理大量数据流时,如视频流或大型文件传输等场景,表现出更好的性能。
  2. 向下兼容:PCI-E网卡可以在所有支持PCI-E接口的主板上使用,无论其它硬件接口版本如何。这使得PCI-E网卡在多种系统配置中具有很好的兼容性。
  3. 易于升级:由于PCI-E接口采用串行连接方式,它可以很容易地通过增加信道数量来提升带宽,因此,PCI-E网卡在未来的升级中具有很大的潜力。
  4. 多种形式:PCI-E网卡有多种形式,包括台式机网卡、便携式网卡、无线网卡等,可以满足不同用户的需求。

请注意,虽然PCI-E网卡具有许多优点,但它可能不适合所有的应用场景。例如,对于一些只需要基本网络连接功能的用户,更便宜、更简单的网络解决方案可能更合适。

ifconfig看看

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
eno1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
ether 9c:c2:c4:04:8a:78 txqueuelen 1000 (以太网)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

eno2: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
ether 9c:c2:c4:04:8a:79 txqueuelen 1000 (以太网)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

eno4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet【网络地址】 10.168.157.251 netmask【掩码】 255.255.255.0 broadcast 10.168.127.255
inet6 fe80::9ec2:c4ff:fe04:8a7b prefixlen 64 scopeid 0x20<link>
ether【mac地址】 9c:c2:c4:04:8a:7b txqueuelen 1000 (以太网)
RX packets 404748669 bytes 62270812330 (62.2 GB)
RX errors 0 dropped 45412 overruns 0 frame 0
TX packets 89401903 bytes 29846981462 (29.8 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (本地环回)
RX packets 216531961 bytes 57623160675 (57.6 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 216531961 bytes 57623160675 (57.6 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

修改网卡命名

1
2
3
4
5
6
7
8
9
10
11
12
当工作中大量管理网卡,所有设备的网卡最好都是以 eth0 命名,这样可以批量操作。
网络接口命名修改
网卡命名规则受 biosdevname 和 net.ifnames 两个参数影响
编辑 /etc/default/grup 文件,增加 biosdevname=0 net.ifnames=0
更新 grub
# grub2-mkconfig -o /boot/grub2/grub.cfg
重启
# reboot

组合,biosdevname=0 net.ifnames=0,则网卡名为 eth0
biosdevname=1 net.ifnames=0,则网卡名为 em1
biosdevname=0 net.ifnames=1,则网卡名为 ens33
1
2
mii-tool eth0  查看网卡物理连接情况
route -n 查看网关(路由),使用 -n 参数不解析主机名(把ip解析成域名)

网关基本理解:什么是网关,网关的作用是什么?【里面的例子蛮有趣的】

动手实操:

1
2
3
4
5
6
(base) sv@sv-NF5280M5:/home/sv$ route -n
内核 IP 路由表
目标 网关 子网掩码 标志 跃点 引用 使用 接口
0.0.0.0 10.168.147.10 0.0.0.0 UG 100 0 0 eno4
10.168.147.0 0.0.0.0 255.255.255.0 U 100 0 0 eno4
169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 eno4

网络配置命令

1
2
3
ifconfig <接口> <IP地址> [netmask 子网掩码]      设置网卡的ip地址
ifup <接口> 启用网卡
ifdown <接口> 禁用网卡

网关配置命令

1
2
3
4
添加网关
route add default gw <网关ip>
route add -host <指定ip> gw <网关ip>
route add -net <指定网段> netmask <子网掩码> gw <网关ip>

网络命令集合:ip命令

网络故障排除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ping 检测是否连接到主机
ping www.baidu.com
traceroute 跟踪当前主机到目标主机的网络状态,-w 1超时最多等1
traceroute -w 1 www.baidu.com

mtr 显示自己主机的网络状态

nslookup 域名解析成ip
nslooup www.baidu.com

telnet 检测端口
telnet www.baidu.com 80

tcpdump 网络抓包 -i any 抓取所有网卡里的数据包,-n 把域名解析成 ip ,port 80 抓取指定端口 host 10.0.0.1 抓取当前主机到某个主机的数据包
tcpdump -i any -n port 80
tcpdump -i any -n host 10.0.0.1
tcpdump -i any -n host 10.0.0.1 and port 80
tcpdump -i any -n host 10.0.0.1 and port 80 -w /tmp/filename 捕获并且保存

netstat 监听地址 -n 域名转换,-t 显示tcp ,-p 进程 ,-l tcp状态 listen
netstat -ntpl

ss 跟netstat一样,参数也一样,显示的格式不一样

ping

Ping是用来测试网络连接质量的工具。它通过发送ICMP(Internet Control Message Protocol)回显请求消息到目标主机,并等待回显应答。通过测量这个过程的时间,Ping可以帮助我们了解数据包从一台计算机传输到另一台计算机所需要的时间,从而了解网络的延迟情况。此外,Ping还能帮助我们找出丢包的问题。

1
2
3
4
5
6
7
8
9
10
11
12
(base) sv@sv-NF5280M5:/home/sv$ ping www.baidu.com
PING www.a.shifen.com (183.2.172.42) 56(84) bytes of data.
64 字节,来自 183.2.172.42 (183.2.172.42): icmp_seq=1 ttl=50 时间=32.6 毫秒
64 字节,来自 183.2.172.42 (183.2.172.42): icmp_seq=2 ttl=50 时间=33.1 毫秒
64 字节,来自 183.2.172.42 (183.2.172.42): icmp_seq=3 ttl=50 时间=32.5 毫秒
64 字节,来自 183.2.172.42 (183.2.172.42): icmp_seq=4 ttl=50 时间=32.8 毫秒
64 字节,来自 183.2.172.42 (183.2.172.42): icmp_seq=5 ttl=50 时间=32.6 毫秒
64 字节,来自 183.2.172.42 (183.2.172.42): icmp_seq=6 ttl=50 时间=32.8 毫秒
^C
--- www.a.shifen.com ping 统计 ---
已发送 6 个包, 已接收 6 个包, 0% 包丢失, 耗时 5008 毫秒
rtt min/avg/max/mdev = 32.530/32.750/33.089/0.189 ms

traceout

Traceroute是用来追踪数据包在网络上从源主机到目标主机的路径的工具。它通过发送一系列的ICMP请求消息,并记录每一跳的IP地址和传输时间,从而找出数据包在网络中的完整路径。Traceroute对于诊断网络中的路由问题非常有用。

traceout原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(base) sv@sv-NF5280M5:/home/sv$ traceroute -w 1 www.baidu.com
traceroute to www.baidu.com (183.2.172.42), 30 hops max, 60 byte packets
1 10.168.157.1 (10.168.157.1) 0.264 ms 0.245 ms 0.235 ms
2 * * *
3 10.168.82.2 (10.168.82.2) 1.305 ms 1.775 ms 2.248 ms
4 172.16.255.254 (172.16.255.254) 0.897 ms 1.018 ms 0.795 ms
5 113.140.11.1 (113.140.11.1) 2.604 ms 1.501 ms 1.590 ms
6 10.224.27.5 (10.224.27.5) 1.483 ms 10.224.27.9 (10.224.27.9) 1.658 ms 1.715 ms
7 1.85.253.45 (1.85.253.45) 1.777 ms 1.85.253.53 (1.85.253.53) 1.764 ms *
8 * 202.97.36.109 (202.97.36.109) 31.468 ms 202.97.13.253 (202.97.13.253) 29.065 ms
9 113.96.4.74 (113.96.4.74) 33.720 ms * *
10 * * *
11 14.29.117.178 (14.29.117.178) 31.263 ms 14.29.117.170 (14.29.117.170) 39.950 ms 37.211 ms
12 * * *
13 * * *
14 * * *
15 * * *

Ping与Traceroute的区别
主要区别在于Ping主要用于测试网络连接的质量(如延迟和丢包),而Traceroute主要用于追踪数据包的路径。Ping只告诉你数据包是否能够到达目标主机,以及这个过程需要多长时间,但它不能告诉你数据包到达目标主机的具体路径。而Traceroute则能详细地展示数据包从源主机到目标主机的每一跳路径,有助于我们了解网络的结构和找出可能存在的路由问题。

mtr

1
2
3
4
5
6
(base) sv@sv-NF5280M5:/home/sv$ mtr                                                       My traceroute  [v0.93]
sv-NF5280M5 (127.0.0.1) 2024-05-10T16:29:13+0800
Keys: Help Display mode Restart statistics Order of fields quit
Packets Pings
Host Loss% Snt Last Avg Best Wrst StDev
1. localhost 0.0% 9 0.0 0.0 0.0 0.0 0.0

netstat

netstat是一个非常实用的命令,它可以帮助我们了解我们的系统网络状态。以下是一些基本的使用方法:

  1. 显示网络状态:netstat 命令可以显示网络状态,它通常用于问题确定而不是性能测量。但是,netstat 命令可用于确定网络上的流量,以确定性能问题是否是由于网络拥塞引起的。在 netstat 关于所配置的网络接口,诸如以下的流量命令显示信息:与所有sockets关联的信息。详情请参考此链接
  2. 网络统计工具:netstat 是一个网络分析工具,用于显示网络连接、路由表、接口统计、伪装连接和多播成员资格等信息。然而随着时间的推移,一些Linux发行版已经开始用像ss, ip这样的更现代的工具代替netstat。详情请参考此链接
  3. 显示端口和网络统计数据:netsta命令是一个CLI工具,用于网络统计。它提供了网络活动的概览,并显示哪些端口是开放的或已建立连接。netstat 工具对于发现网络问题至关重要。详情请参考此链接

在使用 netstat 命令时,需要注意的是,由于其强大的功能,可能需要管理员权限才能获取完整的网络状态信息。

网络管理和配置文件

1
2
3
4
5
6
7
网络服务管理程序分为两种,分别是 SysV 和 systemd(centos7)
service network status|start|stop|restart

网络配置文件

/etc/sysconfig/network-scripts/ifcfg-eth0 (网卡配置项)
/etc/hosts

常用命令

下面是一些常见的netstat操作:

  1. 显示所有活动的网络连接:netstat命令默认就可以显示当前系统的所有网络连接信息。
  2. 显示监听的服务器套接字:netstat -l可以显示所有正在监听的服务器套接字。
  3. 显示路由表:netstat -r可以显示路由表,这对于诊断网络问题非常有用。
  4. 显示每个协议的统计信息:netstat -s可以显示每个网络协议的统计信息,如TCP、UDP、ICMP等。
  5. 显示网络接口的统计信息:netstat -i可以显示每个网络接口的统计信息,如发送和接收的数据包数量等。

软件包管理

软件包管理器

包管理器是方便软件安装、卸载,解决软件依赖关系的重要工具。

  • CentOS 和 RedHat 使用 yum 包管理器,软件安装包格式为 rpm
  • Debian、Ubuntu使用 apt 包管理器,软件安装包格式为 deb

使用rpm命令安装软件包

image-20240510193643483

1
2
3
4
rpm 命令常用参数
-q 查询软件包    rpm -qa 查询所有软件包    rpm -q vim-common 查询某个软件包
-i 安装软件包    rpm -i vim-enhanced-7.4.160-5.el7.x84_64.rpm (要全称)
-e 卸载软件包    rpm -e vim-enhanced (只要名字,不需要版本号等)用 rpm 安装的问题:如果一个软件包依赖其他软件包,那么就会安装失败。需要操作者自己解决依赖关系。

使用yum包管理器安装软件包

rpm 包的问题

  • 需要自己解决依赖关系
  • 软件包来源不可靠
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CentOS yum源
http://mirror.centos.org/centos/7/
国内镜像
https://opsx.alibaba.com/mirror
yum 配置文件
/etc/yum.repos.d/CentOS-Base.repo

可以修改配置文件
[base]
name=CentOS-$releasever - Base -mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/os/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7

或者直接用别人已经写好的配置文件
wget -O /etc/yum.repo.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo需要清除缓存yum makecache

yum 命令常用选项

1
2
3
4
5
6
常用选项

install 安装软件包
remove 卸载软件包
list |grouplist 查看软件包
update 升级软件包

其他方式安装

1
2
3
4
5
6
7
8
9
二进制安装
源代码编译安装

wget https://openresty.org/download/openresty-1.15.8.1.tar.gz
tar zxf openresty-VERSION.tar.gz
cd openresty-VERSION/
./configure --prefix=/usr/local/openresty
make -j2 (用2核编译)
make isntall

升级内核

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
33
34
35
rpm 格式内核
查看内核版本
uname -r
升级内核版本
yum install kernel-3.10.0 这种方式一般不能升级到最新
epel软件仓库会有较高的软件版本。yum install epel-release -y
升级已安装的其他软件包和补丁
yum update 除了升级内核,还会升级软件包。正常不要使用。


源代码编译安装内核
yum install gcc gcc-c++ make ncurses-devel openssl-devel elfutils-libelf-devel

下载并解压缩内核
https://www.kernel.org
tar xvf linux-5.1.10.tar.xz -C /usr/src/kernels

配置内核编译参数
cd /usr/src/kernels/linux-5.1.10/
make menuconfig | allyesconfig | allnoconfig
make allyesconfig (无脑全选)

使用当前系统内核配置
cp /boot/config-kernelversion.platform /usr/src/kernels/linux-5.1.10/.config


查看cpu
lscpu

编译
make j2 all

安装内核
make modules_install
make install

这篇教程详细记录了每个步骤:linux内核编译记录

进程管理

进程的概念与进程查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
进程-运行中的程序,从程序开始运行到终止的整个生命周期是可管理的

查看命令
ps
-e 表示所有的终端运行的进程
-f 显示更多信息,比如 UID、PPID(父进程)、CMD(命令的完整路径)
-L 多显示 LWP ,线程信息
ps -eLf 常用命令

pstree 查看进程树

top 动态查看进程信息top -p 进程号

结论:
进程也是树形结构
进程和权限有着密不可分的关系

ps

1
2
3
4
(base) sv@sv-NF5280M5:/home/sv$ ps
PID TTY TIME CMD
1221450 pts/1 00:00:03 bash
1247704 pts/1 00:00:00 ps

“pts/1” 是一种特殊的终端设备文件,表示的是一种伪终端(Pseudo-Terminal Slave)。在这里,“pts” 是伪终端的缩写,数字 “1” 是这个伪终端的编号。

top

image-20240510195736332

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
第一行 
34min 表示这台机器已经启动34分钟没有关机了
2users 表示有2个用户登录
平均负载:1分钟,5分钟,15分钟

第二行
一共运行的任务,几个在running ,几个在sleeping

第三行(平均值,按 1 会把所有 逻辑cpu 的使用情况列出来)
2.8 us 1.8 sy 97.7 id 0.0 wa
us 表示用户计算,sy表示进程之间状态交互,id表示空闲,wa表示磁盘等待

第四行
内存状态
第五行
交换分区(虚拟内存)

进程的优先级调整

1
2
3
4
5
6
7
8
9
10
11
12
调整优先级
nice 范围从 -20 到 19,值越小优先级越高,抢占资源就越多
nice -n 10 ./rest.sh 启动的时候调整为 10
renice 重新设置优先级
renice -n 15 19312 已经处于启动的情况下进行调整。根据进程号
进程的作业控制
&符号,后台运行
./test.sh &
jobs 把处于后台运行的程序调到前台显示
jobs 能得到一个编号
fg 编号,可以调到前台
ctrl +z,把已经处于前台的程序调到后台,状态会stop

进程的通信方式-信号

1
2
3
4
5
信号是进程间通信方式之一,典型用法是:终端用户输入中断命令,通过信号机制停止一个程序的运行。
使用信号的常用快捷键和命令
kill -l 查看所有的信号
SIGINT 通知前台进程组终止进程 ctrl + c,2号信号
SIGKILL 立即结束程序,不能被阻塞和处理 kill -9 pid ,9号信号

守护进程和系统日志

1
2
3
4
5
6
7
8
9
10
11
12
守护进程(精灵进程)

使用 nohup 与 & 符号配合运行一个命令 (nohup进程不是守护进程)
nohup 命令使进程忽略 hangup(挂起)信号。关掉终端这个进程依然可以运行,忽略输入并且把输出打印到 nohup.out
守护进程(daemon)和一般进程有什么差别呢?
开机自启,守护进程不需要终端,输出可以打印到特殊的文件中,进程所占用的目录是根目录。cd /proc/ 这个目录是内存信息,相应的进程会有进程号同名的目录。

使用 screen 命令,进入screen环境后,如果远程连接断掉了,可以通过screen恢复工作现场
screen 进入 screen 环境
ctrl +a然后再单独按d退出(detached)screen 环境
screen -ls 查看 screen 的会话
screen -r sessionid 恢复会话系统日志文件 /var/log系统常规日志:messages内核运行情况:dmesg安全日志 secure定时任务日志 cron

服务管理工具systermctl

服务(提供常见功能的守护进程)集中管理工具

  • service
  • systemctl(centos7以后的,可以看做service进化版)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
service 启动脚本
cd /etc/init.d/ 目录下
vim network 可以查看network的启动脚本,200多行,完全由编写人员自己控制,比较复杂;


systemctl 启动脚本
cd /usr/lib/systemd/system/
vim sshd.service

原有的init,linux的1号进程
init 0 关机 (不能用kill -9杀掉这个进程,只能0结束这个进程,进而关机)
init 6 重启
init 3 字符终端
init 5 图形界面

systemctl 常见操作
systemctl status|start|stop|restart|reload|enable|disable 服务名称
1、restart 和reload差别,reload不停服务,直接重启
2、enable开机启动,disable不开机启动

启动Docker

1
systemctl start docker

SELinux

MAC(强制访问控制)和DAC(自主访问控制)。SELinux就是 MAC,生产环境不太用,比较麻烦。

1
2
3
4
5
6
7
8
9
10
11
根据进程pid查端口
lsof -i |grep pid

根据端口port查进程
lsof -i:port

根据进程pid查端口
netstat -nap |grep pid

根据端口port查进程
netstat -nap |grep port

内存和磁盘管理

内存和磁盘使用率查看

1
2
3
4
5
内存使用率查看
free
-m 以兆的方式显示
-g 以G的方式显示,但是会被四舍五入。一般不用
top

看看电脑先

1
2
3
4
5
6
7
8
9
10
11
12
(base) sv@sv-NF5280M5:/home/sv$ free -m apport.log
总计 已用 空闲 共享 缓冲/缓存 可用
内存: 64029 20697 2641 789 40690 41890
交换: 2047 894 1153
(base) sv@sv-NF5280M5:/home/sv$ free
总计 已用 空闲 共享 缓冲/缓存 可用
内存: 65566072 21394584 2503952 808044 41667536 42695292
交换: 2097148 916176 1180972
(base) sv@sv-NF5280M5:/home/sv$ free -g
总计 已用 空闲 共享 缓冲/缓存 可用
内存: 62 20 2 0 39 40
交换: 1 0 1

交换空间(Swap Space)是硬盘上的一块区域,它被操作系统用作虚拟内存,用来临时存放内存中的数据。当系统的物理内存用完时,操作系统会将一些不常用的数据移动到交换空间,从而释放出物理内存给需要的程序使用。

不用Swap的话就随机杀掉。

1
2
3
4
磁盘使用率的查看
fdisk
-l 查看
磁盘分区一块硬盘最多分15个分区

实操

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(base) sv@sv-NF5280M5:/home/sv$ sudo fdisk -l
[sudo] sv 的密码:
Disk /dev/loop1:4 KiB,4096 字节,8 个扇区
单元:扇区 / 1 * 512 = 512 字节
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节


Disk /dev/loop2:6.77 MiB,7081984 字节,13832 个扇区
单元:扇区 / 1 * 512 = 512 字节
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节


Disk /dev/loop3:40.44 MiB,42393600 字节,82800 个扇区
单元:扇区 / 1 * 512 = 512 字节
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节

问个问题,为什么要对磁盘分区?

磁盘分区基本上是把一个磁盘分成一个或多个逻辑磁盘。每个分区都像一个独立的硬盘一样,有自己的文件系统。在操作系统中,磁盘分区通常被表示为不同的驱动器,如C盘、D盘等。对磁盘进行分区的原因主要有以下几点:

  1. 提高磁盘效率:文件系统通常会在磁盘上留有一些空间,这样可以提高读写速度。如果你只有一个大的分区,那么这个空间可能就会浪费很多。如果你有多个小的分区,那么每个分区的空间都会更加合理地利用。
  2. 数据安全:如果你的操作系统崩溃,那么可能会损坏整个文件系统。如果你有多个分区,那么一个分区的损坏不会影响其他分区。这样,你的数据就更安全了。
  3. 多操作系统:如果你想在一台计算机上安装多个操作系统,那么你需要为每个操作系统创建一个分区。这样,每个操作系统都可以在自己的分区上运行,互不干扰。
  4. 文件组织:分区可以帮助你更好地组织文件。例如,你可以在一个分区上存储系统文件,在另一个分区上存储个人文件。这样,即使系统分区出现问题,你的个人文件也不会受到影响。

以上就是对磁盘进行分区的主要原因。

每个磁盘分区都可以被格式化为一个独立的文件系统。

1
2
3
df 既能够看到分区,又能够看到挂载到的目录
-h 人性化可读
系统中各个文件系统的磁盘使用情况

实操

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
(base) sv@sv-NF5280M5:/dev$ df -h
文件系统 容量 已用 可用 已用% 挂载点
udev 32G 0 32G 0% /dev
tmpfs 6.3G 2.8M 6.3G 1% /run
/dev/sda2 439G 253G 165G 61% /
tmpfs 32G 396K 32G 1% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 32G 0 32G 0% /sys/fs/cgroup
/dev/loop1 128K 128K 0 100% /snap/bare/5
/dev/loop4 56M 56M 0 100% /snap/core18/2812
/dev/loop5 64M 64M 0 100% /snap/core20/2182
/dev/loop6 75M 75M 0 100% /snap/core22/1122
/dev/loop18 350M 350M 0 100% /snap/gnome-3-38-2004/140
/dev/loop17 13M 13M 0 100% /snap/snap-store/959
/dev/loop13 350M 350M 0 100% /snap/gnome-3-38-2004/143
/dev/loop19 92M 92M 0 100% /snap/gtk-common-themes/1535
/dev/loop14 219M 219M 0 100% /snap/gnome-3-34-1804/90
/dev/loop12 82M 82M 0 100% /snap/gtk-common-themes/1534
/dev/loop10 219M 219M 0 100% /snap/gnome-3-34-1804/93
/dev/sda1 511M 6.1M 505M 2% /boot/efi
/dev/sdb2 3.6T 420G 3.0T 13% /data
tmpfs 6.3G 76K 6.3G 1% /run/user/1000
/dev/loop21 40M 40M 0 100% /snap/snapd/21184
/dev/loop2 6.9M 6.9M 0 100% /snap/ngrok/138
/dev/loop9 505M 505M 0 100% /snap/gnome-42-2204/172
/dev/loop16 13M 13M 0 100% /snap/snap-store/1113
/dev/loop20 64M 64M 0 100% /snap/core20/2264
/dev/loop11 506M 506M 0 100% /snap/gnome-42-2204/176
/dev/loop22 7.0M 7.0M 0 100% /snap/ngrok/148
/dev/loop15 75M 75M 0 100% /snap/core22/1380
/dev/loop8 39M 39M 0 100% /snap/snapd/21465
/dev/loop23 56M 56M 0 100% /snap/core18/2823
  • 在Linux系统中,tmpfsudev/dev/sda2都是你的系统挂载点上的文件系统。

    1. tmpfs:tmpfs是一种基于内存的文件系统,它将一部分RAM作为一个挂载点,允许你像操作磁盘分区一样操作内存。因为它存储在内存中,所以读写速度非常快。然而,一旦系统重启,存储在tmpfs中的所有数据都会丢失。

    2. udev:udev文件系统是一个动态设备管理器,它管理/dev目录下的设备节点。udev允许设备管理工作在用户空间中完成,提供了一种灵活的方式来管理设备节点,并允许通过设备的物理属性或者热插拔事件来改变设备的配置。

      • udev就是这样的一个动态设备管理器。当一个设备被接入到系统中,udev会根据设备的类型和属性,动态地在/dev目录下创建一个设备节点,这样应用程序就可以通过这个设备节点来访问设备。当设备被移除时,udev会删除对应的设备节点。

        例如,当你插入一个USB设备时,udev会在/dev下创建一个像是sdb1的设备节点,你就可以通过这个设备节点来访问你的USB设备。当你移除USB设备时,/dev/sdb1这个设备节点就会被删除。

    3. /dev/sdaX/dev/sda2/dev/sdb2 这两个设备。这里的 sdasdb 分别代表系统中的第一块和第二块硬盘,而后面的数字 2 表示的是这个硬盘上的第二个分区。

    至于为什么你在fdisk -l的输出中看不到这些分区,这是因为fdisk只显示物理磁盘分区,而不显示基于内存的文件系统(如tmpfs)或特殊的文件系统(如udev)。你可以使用df -hmount命令来查看所有的挂载点和文件系统,包括tmpfsudev

1
2
3
du (实际占用的空间)
-h 人性化显示
-s 只显示总计

挂载点就是这些物理设备在文件系统中的位置。当一个设备被"挂载"到一个挂载点时,这个设备的内容就可以通过访问这个挂载点来访问了。

举个例子,如果你插入一个USB驱动器,系统可能会自动将这个驱动器挂载到/media/your_username/usb_drive这个目录下,那么你就可以通过访问这个目录来查看和操作这个USB驱动器的内容。

du与ls的区别
du 是实际占用的,ls算上空洞数据。

常见文件系统

1
2
3
4
Linux 支持多种文件系统,常见的有
ext4(centos6)
xfs(centos7)
NTFS(需安装额外软件,window常用,有版权)

ext4文件系统

1
2
3
4
5
ext4文件系统基本结构比较复杂
超级块
超级块副本
i节点(inode)
数据块(datablock)
1
2
3
4
5
6
(base) sv@sv-NF5280M5:/home/sv/LANet$ du -h utils.py
4.0K utils.py
(base) sv@sv-NF5280M5:/home/sv/LANet$ ls -l utils.py
-rw-r--r-- 1 root root 3322 1117 15:51 utils.py
(base) sv@sv-NF5280M5:/home/sv/LANet$ ls -li utils.py
19200499 -rw-r--r-- 1 root root 3322 1117 15:51 utils.py

为社么vim会改变i节点,echo不会改变i节点

Vim和echo命令在处理文件时的行为确实有所不同。

当你使用Vim编辑并保存一个文件时,Vim实际上是创建了一个新的文件来替代旧的文件。这个新文件会有一个新的i节点,所以你会看到i节点的数值发生了变化。

这样做的好处是,如果在保存文件时发生错误(比如磁盘空间不足),你仍然可以保留原来的文件,不会丢失数据。同时,Vim还会记录下每次修改的时间和用户等信息。

相比之下,echo命令则更简单。它直接将输出追加到文件中,不会创建新的文件,因此i节点的数值不会改变。

另外,文件的权限也可能影响i节点的变化。如果文件没有写权限,Vim在保存时会创建新的文件,从而改变i节点。如果你给文件添加了写权限(比如使用chmod o+w filename命令),则Vim在保存时不会改变i节点。

总的来说,这两个命令在处理文件时的行为差异,反映了它们的设计理念和使用场景的不同。Vim是一个功能强大的文本编辑器,它提供了丰富的编辑功能和数据保护机制;而echo更多地被用来在脚本中输出文本或者简单地向文件中追加内容。

rm只是将i节点和数据块断开

因此有了ln命令,看个例子,硬链接

1
2
3
4
5
6
7
8
9
10
11
12
(base) sv@sv-NF5280M5:/home/sv/LANet$ ls -li utils.py
19200499 -rw-r--r-- 1 root root 3322 11月 17 15:51 utils.py
(base) sv@sv-NF5280M5:/home/sv/LANet$ ls -li utils.py
19200499 -rw-r--r-- 1 root root 3322 11月 17 15:51 utils.py
(base) sv@sv-NF5280M5:/home/sv/LANet$ ln utils.py utils1.py
ln: 无法创建硬链接 'utils1.py' => 'utils.py': 不允许的操作
(base) sv@sv-NF5280M5:/home/sv/LANet$ ls -li utils.py
19200499 -rw-r--r-- 1 root root 3322 11月 17 15:51 utils.py
(base) sv@sv-NF5280M5:/home/sv/LANet$ sudo ln utils.py utils1.py
[sudo] sv 的密码:
(base) sv@sv-NF5280M5:/home/sv/LANet$ ls -li utils.py
19200499 -rw-r--r-- 2 root root 3322 11月 17 15:51 utils.py

软连接:不同分区

1
2
3
4
(base) sv@sv-NF5280M5:/home/sv/LANet$ ls -li utils.py
19200499 -rw-r--r-- 1 root root 3322 1117 15:51 utils.py
(base) sv@sv-NF5280M5:/home/sv/LANet$ ls -li utils1.py
19200215 lrwxrwxrwx 1 sv sv 8 510 21:19 utils1.py -> utils.py

硬链接和软链接的区别

硬链接和软链接(也被称为符号链接)都是Unix和Linux文件系统中的概念,它们是文件的两种不同类型的链接。

  1. 硬链接:硬链接是一个指向文件的i节点的引用。i节点是文件系统中存储文件元数据(如文件大小、创建日期等)的数据结构。硬链接可以看作是同一文件的不同名字,它们可以位于同一文件系统的不同位置,但都指向同一i节点。删除一个硬链接不会影响到其他的硬链接,因为它们都直接指向同一i节点。【取别名】
  2. 软链接:软链接(或符号链接)则类似于Windows中的快捷方式。它是一个独立的文件,包含了指向另一个文件或目录的路径。软链接可以跨越不同的文件系统,但如果目标文件被删除,软链接就会变为无效。【存路径】

下面是它们之间的主要区别:

  • 存储方式:硬链接是在文件系统中创建一个新的i节点,它与原文件共享i节点,而软链接是创建一个新的文件,该文件中包含了指向原文件的路径。
  • 跨文件系统:硬链接仅限于在同一文件系统中,而软链接可以链接到其他文件系统的文件。
  • 链接目录:通常,硬链接不能链接目录,而软链接可以。
  • 删除原文件:当原文件被删除后,硬链接仍然可以访问文件的内容,而软链接则会失效。

这就是硬链接和软链接的基本区别。在实际使用中,你可以根据需要选择使用硬链接或软链接。

磁盘分区和挂载

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
常用命令
fdisk
mkfs
parted
mount


常见配置文件
/etc/fstab

用fdisk创建分区(一个硬盘设备可以创建多个分区,也可以创建一个)
1:fdisk -l 查看有几个硬盘设备及分区
2:fdisk /dev/sdc (比如有设备sdc,则可以针对sdc进行分区)
3:之后 m 键是帮助
4:n 表示新建一个分区
5:新建分区时,需要选择主分区和扩展分区,其中 p表示主分区,最多有4个。e表示扩展分区(里面可以建立逻辑分区)。一般把一块硬盘划分为一个主分区。使用扩展分区时,只能建立3个主分区。
6:选择区分编号1-4
7:指定分区扇区大小,默认2048
8:指定分区大小。默认全部。可以 + 20G等可以选择分区大小
9:q 表示退出,分区不生效。w 表示生效

建立完分区后,需要对分区进行格式化。

mkfs.ext4 mkfs.xfs等命令
mkfs.ext4 /dev/sdc1

然后要进行操作,linux里都是文件级别的操作,需要挂载到某个目录下
mkdir /mnt/sdc1
mount /dev/sdc1 /mnt/sdc1 挂载上去
对/mnt/sdc1的读写就会落入sdc1设备上

1、一个硬盘
2、进行分区
3、格式化
4、挂载
5、对指定目录进行操作


需要注意的事情:
如果一个硬盘大于 2T ,不能使用 fdisk 进行分区,需要使用 parted
parted /dev/sdd
help 获取帮助

mount 进行挂载是临时的,不是固化的
vim /etc/fstab
在文件中新增下面一句话
/dev/sdc1 /mnt/sdc1 ext4 defaults(表示权限)0 0

系统综合状态查询

1
2
3
4
5
6
7
8
9
10
使用 sar 命令查看系统综合状态
sar -u 1 10 CPU的查看,每隔1秒做采样,采样10次,
sar -r 1 10 看内存
sar -b 1 10 IO的情况(磁盘读写)
sar -d 1 10 查看每块磁盘的读写
sar -q 1 10 查看进程
使用第三方命令查看网络流量
yum install epel-release
yum install iftop (网络情况)
iftop -p (默认eth0)

Shell

什么是Shell

1
2
3
4
5
6
shell 是命令解释器,用于解释用户对操作系统的操作。

shell有很多
cat /etc/shells

CentOS 7 默认使用的shell是bash

Shell脚本

1
2
3
UNIX的哲学:一条命令只做一件事情
为了组合命令和多次执行命令,使用脚本文件来保存需要执行的命令
赋予该文件执行权限(chmod u+rx filename)

Shell和Bash的区别

Shell 和 Bash 都是命令行界面,但是它们之间存在一些主要的区别。

  1. Shell 是一个通用术语,用于描述一个命令行解释器(或脚本解释器)。它是用户与操作系统进行交互的接口。在 Unix 和类 Unix 系统(如 Linux)中,有多种不同的 shell 可供选择,如 Bourne shell(sh)、C shell(csh)、Korn shell(ksh)等等。
  2. Bash(Bourne Again SHell)是 Bourne shell 的扩展,也是 Linux 默认的 shell。它增加了许多特性,如命令行编辑、命令历史记录等,使得用户在使用命令行时更加方便。

所以,可以说所有的 Bash 都是 Shell,但并非所有的 Shell 都是 Bash。如果你在 Linux 系统中打开一个终端窗口,你通常会得到一个 Bash shell。如果你在编写 shell 脚本,你可以选择使用 Bourne shell 语法(这样脚本可以在所有的 Unix-like 系统上运行),或者使用 Bash 语法(这样你可以使用 Bash 提供的额外特性,但脚本可能无法在只有 Bourne shell 的系统上运行)。

标准的Shell脚本要包含哪些元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Sha-Bang
命令
#”号开头的注释
chmod u+x filename 可执行权限


执行命令
bash ./filename.sh 会生成一个子进程(不需要执行权限)
./filename.sh 会生成一个子进程,使用Sha-Bang (需要可执行权限)
source ./filename.sh 在当前进程运行
. filename.sh (点之后会产生一个子进程)

比如一个脚本如下:
#! /bin/bash
cd /tmp

在/home目录下运行
bash ./filename.sh 运行,子进程运行cd,然后子进程结束,此时pwd,还是在 /home 而不是/tmp

source ./filename.sh 或者 . filename.sh

内建命令和外部命令的区别
内建命令不需要创建子进程,内建命令比如source
内建命令对当前shell生效

Sha-Bang

用于指明执行这个脚本文件的解释器

管道与重定向

管道与管道符

1
2
3
4
5
管道和信号一样,也是进程通信的方式之一
匿名管道(管道符)是 Shell 变成经常用到的通信工具
管道符是“|”,将前一个命令执行的结果传递给后面的命令
ps | cat
echo 123 | psecho 123 |cat |cmd 可以连续使用

可以看到 cat 和 ps 是两个进程,两个进程之间的通信被连接起来。

重定向符号

理解箭头的方向即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
一个进程默认会打开标准输入、标准输出、错误输出三个文件描述符
输入重定向符号 “<”
read var < /path/to/a/file
(base) sv@sv-NF5280M5:/home/sv/LANet$ wc -l < /etc/passwd
53


输出重定向符号 ">" ">>" "2>" "&>"

echo 123 > /path/to/a/file 清空再输入
echo 123 >> /path/to/a/file 追加
2> 命令执行过程中有错误则重定向
&> 命令执行过程中无论正确错误都重定向

输入和输出重定向组合使用
cat > /path/to/a/file.sh << EOF
i am $USER
EOF

运行以上三句话,会生成一个file.sh文件,文件里内容为i am $USER

补充:echo 命令在Linux中用于在标准输出设备(通常是终端或屏幕)上显示一行文本

来看看这条命令

1
2
3
4
5
6
7
8
9
10
11
(base) sv@sv-NF5280M5:/home/sv/LANet$ cat a.sh
#! /bin/bash
cat > ./file.sh << EOF
i am $USER
EOF
(base) sv@sv-NF5280M5:/home/sv/LANet$ vim a.sh
(base) sv@sv-NF5280M5:/home/sv/LANet$ bash ./a.sh
(base) sv@sv-NF5280M5:/home/sv/LANet$ ls
a.sh file.sh README.md tmp train2017.zip utils1.py utils.py
(base) sv@sv-NF5280M5:/home/sv/LANet$ cat file.sh
i am sv

GPT解释:

这条命令是在 Unix/Linux 系统中使用的,用于向文件中写入内容。让我分解一下这条命令:

  1. cat > /path/to/a/file.sh: cat 是 “concatenate” 的缩写,通常用于输出一个或多个文件的内容。但是这里我们使用了 > 这个重定向符,意思是把 cat 命令的输出重定向到 /path/to/a/file.sh 这个文件中。如果文件已经存在,这个操作会覆盖原有的内容。如果文件不存在,这个操作会创建一个新的文件。
  2. << EOF: 这是一个叫做 “here document” 的技术。<< 是一个特殊的重定向符,意思是把后面的内容作为输入。EOF 是一个标志,它告诉 shell,这个输入会一直持续到遇到另一个 EOF 为止。
  3. i am $USER: 这是要写入文件的内容。$USER 是一个环境变量,代表当前的用户名。所以这一行的意思是 “我是 当前用户名”。
  4. EOF: 这是前面提到的那个结束标志。遇到这个标志,shell 就知道输入结束了。

所以,总的来说,这条命令的意思是创建一个文件 /path/to/a/file.sh,并向其中写入 “我是 当前用户名” 这样的内容。

变量

变量的赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
变量名的命名规则

字母、数字、下划线
不以数字开头

变量的赋值

为变量赋值的过程中,称为变量替换
变量名=变量值
a=123 (不允许出现空格,shell会认为前面不是变量名而是一个命令,比如reboot =1),会重启

使用let为变量赋值
let a=10+20 (尽量少用,效率很低)

将命令赋值给变量
l=ls (用处不大)

将命令结果赋值给变量,使用$() 或者 ''
letc=$(ls -l /etc)
letc=$'ls /root'

变量值有空格等特殊字符可以包含在 "" 或 '' 中
srring1='hello bash'
string2="hello I'm name"

变量引用及作用范围

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
变量的引用
${变量名}称作对变量的引用
echo ${变量名} 查看变量的值
${变量名} 在部分情况下可以省略为 $变量名

变量的作用范围
变量的默认作用范围
当前的shell,父进程的变量对子进程无效,子进程的对父进程也无效。
可以使用source
变量的导出
export ,子进程可以获得父进程的变量,同时,父进程也能看到子进程的变量
export demo_var1="hello subshell"
变量的删除
unset
unset demo_var1

变量作用范围

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(base) sv@sv-NF5280M5:/home/sv/LANet$ bash
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

-------- freesurfer-linux-ubuntu18_x86_64-7.3.2-20220819-6354275 --------
Setting up environment for FreeSurfer/FS-FAST (and FSL)
FREESURFER_HOME /data/home/qulijun/freesurfer
FSFAST_HOME /data/home/qulijun/freesurfer/fsfast
FSF_OUTPUT_FORMAT nii.gz
SUBJECTS_DIR /data/home/qulijun/freesurfer/subjects
MNI_DIR /data/home/qulijun/freesurfer/mni
sv@sv-NF5280M5:/home/sv/LANet$ echo $a

sv@sv-NF5280M5:/home/sv/LANet$ a=2
sv@sv-NF5280M5:/home/sv/LANet$ exit
exit
(base) sv@sv-NF5280M5:/home/sv/LANet$ echo $a
1

变量的导出:export ,子进程可以获得父进程的变量,同时,父进程也能看到子进程的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(base) sv@sv-NF5280M5:/home/sv/LANet$ echo $demo_var1
hello subshell
(base) sv@sv-NF5280M5:/home/sv/LANet$ bash
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

-------- freesurfer-linux-ubuntu18_x86_64-7.3.2-20220819-6354275 --------
Setting up environment for FreeSurfer/FS-FAST (and FSL)
FREESURFER_HOME /data/home/qulijun/freesurfer
FSFAST_HOME /data/home/qulijun/freesurfer/fsfast
FSF_OUTPUT_FORMAT nii.gz
SUBJECTS_DIR /data/home/qulijun/freesurfer/subjects
MNI_DIR /data/home/qulijun/freesurfer/mni
sv@sv-NF5280M5:/home/sv/LANet$ echo $demo_var1
hello subshell
sv@sv-NF5280M5:/home/sv/LANet$ exit
exit
(base) sv@sv-NF5280M5:/home/sv/LANet$ echo $demo_var1
hello subshell

系统环境变量,预定义变量与位置变量

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
33
34
35
36
环境变量:每个Shell打开都可以获得到的变量
setenv 命令
env | more 查看当前所有的环境变量
echo ${HOME} 查看单个环境变量
$PATH 当前命令的搜索路径
所以要在$PATH 中新增路径,使用PATH=$PATH:新加路径(只对当前终端生效,对子shell生效)
$PS1 当前提示终端

预定义变量
echo $? $$ $0
$? 指上一条命令是否正确执行,echo $?,正确执行返回0,错误1
$$ 显示当前进程 PID
$0 显示当前进程名称

位置变量
$1 $2 ... ${10},需要有{}

比如有脚本 test.sh]如下:
#! /bin/bash
pos1=$1
pos2=$2
echo $pos1
echo $pos2

执行的时候,./test.sh -a -l
会传参进去,可以对脚本进行简化
echo $1
echo $2

考虑到echo $2 的时候 $2 有可能是空值。所以写成下面这样
pos1=$1
pos2=${2}_
echo $pos1
echo $pos2
如果没有传参,则$2默认为_,规避读入的值是空值。但是这么写,如果传参进去,后面会多一个_,所以可以改成下面这样:
pos2=${2-_}

环境变量配置文件

1
2
3
4
5
6
7
8
9
10
配置文件
/etc/profile
/etc/profile.d/
~/.bash_profile
~/.bashrc
/etc/bashrc

所以经常在 /etc/profile 中新增 export PATH=$PATH:/new/path
su - 切换用户会加载4个文件
su 切换用户只会加载~/.bashrc、/etc/bashrc

在 Unix 和 Linux 中,以上这些文件都是环境配置文件,具体作用如下:

  1. /etc/profile:这是系统的全局配置文件,对所有用户都有效。该文件设置了环境变量,包括用户的 shell 环境设置、程序路径等。
  2. /etc/profile.d/:这是一个目录,里面的脚本文件会被 /etc/profile 文件在启动时候执行。这样设计的目的是为了更好的模块化和管理系统环境变量。
  3. ~/.bash_profile:这是针对单个用户的配置文件。每当用户登录时,这个文件就会执行一次。这个文件首先查找 ~/.bashrc 文件,如果找到,就加载该文件。
  4. ~/.bashrc:这也是针对单个用户的配置文件。但是与 ~/.bash_profile 不同的是,~/.bashrc 文件在每次打开新的 shell 时都会执行。这意味着每次打开新的终端窗口或新的 shell 时,都会读取并执行这个文件。
  5. /etc/bashrc:这是系统级别的,对所有用户都有效。当 bash shell 被打开时,都会读取并执行这个文件。

总的来说,这些文件都是用来配置用户的 shell 环境的。其中,/etc/profile/etc/bashrc 是全局的,对所有用户都有效;而 ~/.bash_profile~/.bashrc 是针对每个用户的,只对当前用户有效。

数组

1
2
3
4
5
6
7
8
9
10
11
定义数组
IPTS=(10.0.0.1 10.0.0.2 10.0.0.3)

显示数组的所有元素
echo ${IPTS[@]}

显示数组元素个数
echo ${#IPTS[@]}

显示数组的第一个元素
echo ${IPTS[0]}

转义和引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
特殊字符:一个字符不仅有字面意义,还有元意(meta-meaning)
# 注释
; 分号
\ 转义符号
" 和 ' 引号

单个字符的转义
\n \r \t 单个字母的转义
\$ \" \\ 单个非字母的转义

引用
"" 双引号,如果里面有变量,会进行解释
'' 单引号不会进行解释
` 反引号

运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
赋值运算符
= 赋值运算符,用于算数赋值和字符串赋值
使用 unset 取消为变量的赋值
= 除了作为赋值运算符还可以作为测试操作符


算数运算符

基本运算符
+ - * / ** %

使用expr进行计算
expr 4 + 5 (要有空格,只能支持整数)
num1=`expr 4 + 5`

数字常量的使用方法,如果不用特殊方法,a=4+5,其实把 “4+5”字符串赋值给a
let “变量名=变量值”
变量值使用0开头为八进制,0x开头为十六进制

双圆括号是let命令的简化
((a=4+5))
((a++))
echo $((10+20))

特殊字符大全

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
33
34
35
36
37
38
39
40
41
42
引号
' 完全引用
" 不完全引用
` 执行命令
括号
() (()) $() 圆括号
单独使用圆括号会产生一个子shell(xyz=123)
数组初始化 IPS=(ip1 ip2 ip3)

[] [[]] 方括号
单独使用方括号是测试(test)或数组元素功能
两个方括号表示测试表达式

<> 尖括号 重定向符号

{} 花括号
输出范围 echo{0..9},会输出0-9所有数字
文件复制 cp -v /etc/passwd /etc/passwd.bak
等同于 cp -v /etc/passwd{,.bak}
运算和逻辑符号
+-*/% 算数运算符
><= 比较运算符
&& || !逻辑运算符
(( 5 > 4 && 6> 5)),然后通过 echo $? 判断

转义符号
\

其他符号
# 注释符
; 命令分隔符
case 语句的分隔符要转义 ;;
:空指令
. 和source命令相同
~ 家目录
, 分隔目录
* 通配符
? 条件测试或通配符
$ 取值符号
| 管道符
& 后台运行
空格

测试与判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
退出程序命令
exit 判断上一条命令是否正常,0或者非0
exit 1或者0 返回10 给shell ,返回值非0位不正常退出
$? 判断当前shell前一个进程是否正常退出

测试命令test

test命令用于检查文件或者比较值
test可以做以下测试
文件测试
整数比较测试
字符串测试

test测试语句可以简化为[]符号
test -f /etc/passwd2 判断文件是否存在并且是个普通文件,-e是文件或者目录,-d目录
[ -d /etc/ ]
[]符号还有扩展写法 [[]] 支持 && || < >

if判断语句

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
if-then 语句的基本用法
if [ 测试条件成立 ] 或 命令返回值是否为0
then 执行相应命令
fi 结束

if-then-else 语句可以在条件不成立时也运行相应的命令
if [ 测试条件成立 ]
then 执行相应命令
else 测试条件不成立,执行相应命令
fi 结束

if [ 测试条件成立 ]
then 执行相应命令
elif [ 测试条件成立 ]
then 执行相应命令
else 测试条件不成立,执行相应命令
fi 结束

嵌套 if 的使用
if 条件测试中可以再嵌套 if 条件测试
if [ 测试条件成立 ]
then 执行相应命令
if [测试条件成立]
then 执行相应命令
fi
fi

case分支

1
2
3
4
5
6
7
8
9
10
case 语句和 select 语句可以构成分支

case "$变量" in
"情况1" )
命令...;;;
"情况2" )
命令...;;;
* )
命令...;;;
esac

循环

for循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for 循环的语法
for 参数 in 列表
do 执行的命令
done 封闭一个循环

使用反引号或 $() 方式执行命令,命令的结果当做列表进行处理
列表中包含多个变量,变量用空格分隔
for i in {0..9}
for filename in 'ls *.mp3'
对文本处理,要使用文本查看命令取出文本内容
默认逐行处理,如果文本出现空格会当做多行处理


C 语言风格的 for 命令
for((变量的初始化;循环判断条件;变量变化))
do
命令
done

while循环

1
2
3
4
5
6
while test测试是否成立
do
命令
done

until 循环 与while 循环相反,循环测试为假时,执行循环,为真实循环停止

break和continue

1
2
break 退出
continue 结束本轮循环

使用循环处理位置参数

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
33
34
35
36
37
命令行参数可以使用 $1 $2 ... ${10}..$n 进行读取
$0 代表脚本名称
$* 和 $@ 代表所有位置参数
$# 代表位置参数的数量

有脚本test.sh如下:
#! /bin/bash

# help display help help

for pos in $*
do
if [ "$pos" = "help"]; then
echo $pos $pos
fi
done

运行语句:
bash test.sh a b c help



while 脚本如下:

#! /bin/bash

while [ $# -ge 1]
do
if [ "$1" = "help" ]; then
echo $1 $1
fi
shift
done

shift能够参数左移
运行语句:
bash test.sh a b c help

函数

自定义函数

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
函数用于“包含”重复使用的命令集合

自定义函数
function fname(){
命令
}

函数的执行
fname

函数作用范围的变量
local 变量名


函数的参数
$1 $2...$n

checkpid() {
local i
for i in $* ; do
[ -d "/proc/$i" ] && return 0
done
return 1
}

执行时
checkpid 1 或者 checkpid 1 2
echo $?

系统脚本

1
2
3
4
5
6
7
8
系统自建了函数库,可以在脚本中引用
/etc/init.d/functions

自建函数库
使用 source 函数脚本文件“导入”函数

source /etc/init.d/functions
echo_success

脚本优先级控制

1
2
3
4
5
6
7
8
可以使用 nice 和 renice 调整脚本优先级
避免出现“不可控的”死循环
死循环导致cpu占用过高
死循环导致死机

ulimit -a 可以查看当前终端的使用限制,root用户的话有些限制不会生效

max user processes 用户的最大进程数

计划任务

正则表达式与文本搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
元字符

. 匹配除换行符外的任意单个字符
* 匹配任意一个跟在它前面的字符
[] 匹配方括号中的字符类中的任意一个
^ 匹配开头
$ 匹配结尾
\ 转义后面的特殊字符

扩展元字符
+ 匹配前面的正则表达式至少出现一次
? 匹配前面的正则表达式出现零次或一次
| 匹配它前面或后面的正则表达式


grep 搜索
grep test /root/test.txt

搜索文件

1
2
3
4
5
6
7
8
cd /etc
find passwd
-regex 区分大小写
-iregex 不区分大小写

find /etc -regex .*wd

find * txt -exec rm -v {} \;

sed和awk行编辑器

1
2
3
4
5
6
7
8
9
sed 一般用于对文本内容做替换

sed '/user1/s/user1/u1' /etc/passwd

awk 基本用法
awk 一般用于对文本内容进行统计,按需要的格式进行输出
cut 命令:cut -d:-f 1/etc/passwd
awk 命令:awk -F: '/wd$/{print$1}' /etc/passwd

最后,我们看看快速启动muduo脚本的编写

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
#!/bin/bash # 这行表示这个脚本文件将由 bash shell 来执行。

set -e # 这行命令表示如果后面的命令返回非零退出状态,则立即退出脚本。

# 下面的if语句表示如果当前目录下不存在名为build的文件夹,则创建这个文件夹。
if [ ! -d `pwd`/build ]; then
mkdir `pwd`/build
fi

rm -rf `pwd`/build/* # 删除 build 文件夹下的所有文件和子目录。

# 切换到 build 目录,然后使用 CMake 生成 Makefile 并使用 make 命令编译项目。
cd `pwd`/build &&
cmake .. &&
make

cd .. # 切换回项目的根目录。

# 下面的if语句表示如果 /usr/include/mymuduo 文件夹不存在,则创建这个文件夹。
if [ ! -d /usr/include/mymuduo ]; then
mkdir /usr/include/mymuduo
fi

# 遍历当前目录下的所有 .h 文件,并将它们复制到 /usr/include/mymuduo 文件夹。
for header in `ls *.h`
do
cp $header /usr/include/mymuduo
done

cp `pwd`/lib/libmymuduo.so /usr/lib # 将 libmymuduo.so 文件复制到 /usr/lib 文件夹。

ldconfig # 刷新动态链接库缓存

这段脚本的主要目的是编译一个项目并将生成的头文件和库文件复制到系统的相应目录。