前情提要:本文出现了 CentOS 和 Ubuntu 混用的情况,不过两者除了一些基础的配置和包管理器不同外,大部分命令都是通用的,因此无需太在意这些。如果出了问题,建议百度,基本上都能找到答案。
2022.04.30
Windows 的 WSL2 本质上就是个虚拟机,我已经试过了。不少命令与 linux 是一模一样的,但是微软还是夹带了不少私货,在很多配置上”自以为是、自作主张“地替用户设置好了。要命的是,用户却无权去修改这些配置(就算少部分能修改,步骤也不甚繁琐)。比如每次在 PC 重启的时候 Hyper-V 会重新给 WSL 分配 IP,重新写入一些文件以覆盖之前的网络配置。诸如此类,不胜枚举……
1. 根目录结构
注意:Linux 的根目录不能作任何修改!!!否则后果自负
目录 | 用途 |
---|---|
/bin | binary,存放命令的二进制程序。 有些目录中也有 bin 目录,如 /usr/bin ,/usr/loacl/bin ,也是存放命令的二进制程序。 |
/sbin | superuser bin,存放超级用户(类似 Windows 中的管理员)使用的命令。 同上,也有 /usr/sbin 、/usr/local/sbin 。 |
/root | /root 为超级用户(root 用户)的主目录,系统只有一个 root 用户。 |
/home | 普通用户的主目录,其中包含了创建的各个用户。 比如创建了 xiaolong 和kitty 2个用户,那么便有/home/xiaolong 和/home/kitty 两个用户目录。每个用户目录都有各自的Desktop 、Music 、Document 等子目录。~ 代表当前用户的主目录。如果是普通用户,则主目录是/home ;如果是超级用户 root ,则主目录是/root 。 |
/lib | library,系统所需的动态链接共享库,类似 Windows 中的 DDL 文件,几乎所有的应用程序都会用到这些共享库。 |
/etc | etcetera ,表示“其他、等等”的意思,存放配置文件,如 MySQL 的配置文件 my.conf 。 |
/usr | unix software resource,类似 Windows 中的ProgramFiles 目录。/usr/src 存放内核源码。/usr/local 存放软件的安装目录。 |
/boot | 存放启动 Linux 的相关文件。 |
/proc | process,虚拟目录,是系统内存的映射,用来获取系统信息,其内容不在硬盘上,而是内存中,因而每次开机后都是不一样的。 |
/srv | serve,存放一些服务启动之后需要提取的数据。 |
/dev | device,存放外部设备。 |
/media | 将识别的 U 盘、光驱等设备挂载到该目录。 |
/mnt | mount,临时挂载文件系统。 比如:若将光驱挂载在 /mnt 上,然后进入该目录就可以查看光驱里的内容。再比如,虚拟机开启与与宿主机之间的共享文件夹之后,该共享文件夹便位于 /mnt/hgfs/ 目录下(实际上,linux 与开发者的 os 并不在同一台计算机中,因此更常用远程登录)。 |
/opt | optional,放一些其他文件,由用户自己决定,不受限制。 |
2. 常见 Linux 命令
终端中ctrl+shift+c
复制,ctrl+shift+v
粘贴。
su root
切换到超级用户,su [username]
切换到普通用户。
Linux 命令的选项可以写在中间,也可以写在后面,随个人习惯。
另外,Linux 中的命令数不胜数,选项更是多到不可能记得住。因此记住常用的几个,其他的类似的命令大同小异,建议查手册。
2.1 查看
2.1.1 普通文件内容
cat,catenate,原意为连接、耦合。命令作用为查看文件信息。
head,查看文件前面几行(不带选项的话默认10行)
tail,查看文件末尾几行(不带选项的话默认10行)
more,分页查看文件内容(回车下滑, q 退出)
2.1.2 CPU 、内存、硬盘的使用情况
-
通过
top
查看系统运行状态解释一下第 1 行和第 3 行:
-
第 1 行:基本信息
20:15:52
表示当前时间;up 9:29
表示从系统启动开始到目前的运行时间;1 user
表示当前连接到系统的用户数(终端数);load average
表示系统当前的负载均衡值。0.00 、0.01 、0.05 这 3 个值分别是 1 、5 、15 分钟前进程的平均数。当这三个值的均值大于 0.7 时,说明系统当前负载过大,需要对系统性能调优。 -
第 3 行:各任务占用 CPU 时间的百分比
0.2 us
,user,用户进程0.3 sy
,system,内核进程0.0 ni
,unniced user,优先级不可变的用户进程99.5 id
,idle,空闲 CPU 时间0.0 wa
,wait,等待磁盘 I/O 的 CPU 时间0.0 hi
,hardware interrupt,硬(件)中断0.0 si
,software interrupt,软(件)中断0.0 st
,stolen from this vm by the hypervisor,略。
-
-
也可
free -h
查看内存和交换区 -
df -h
查看整个文件系统(即不包含 swap 区)的硬盘使用情况
-
du [选项] [目录]
查看指定目录下的文件大小,若不加上目录,默认当前目录选项 作用 -h human,人性化地带上单位显示大小 -a 显示所有文件,包括子目录下的文件 -c calculat,计算总量
2.2 ls 列出目录内容
选项 | 作用 |
---|---|
-l | 按列表显示,ls -l |
-a | 显示目录下的所有文件(普通类型文件和目录型文件),ls -la (等价于 ll) |
-i | 显示 inode 号,ls -li |
-h | human ,显示文件大小并人性化地设置合理的单位,ls -lh |
-R | 递归显示文件,及目录的子目录、子目录的文件....,依次递归下去,直至最后是普通文件。 |
ls -l 显示的信息中,开头是由 10 个字符构成的字符串:
-
第 1 个字符表示文件类型,如下:
字符 类型 - 普通文件 d 目录文件 l 符号链接(软链接),快捷方式 b 块设备文件,如磁盘 c 字符设备文件,如鼠标、键盘等 p 管道文件 s 套接字文件 -
Linux 中只有两种类型的组用户:所在组(拥有者所在的组)、其他组。后面 9 个字符表示文件的访问权限,分为 3 对:
- 第 1 对表示文件所有者的权限。
- 第 2 对表示所有者的同组用户的权限。
- 第 3 对表示其他组权限。
每对 3 位,分别表示对文件的读、写、执行权限:
字符 权限 r 读,可用 4 表示 w 写,可用 2 表示 x 执行,目录型文件则是访问,可用 1 表示 - 没有设置权限
# > file 把前面命令输出的内容写(覆盖)到文件 file 中,如:
echo "ok" > ./info.txt
echo "Hello World" > ./info.txt
# echo 显示的文本的引号可以省略,但是不建议省略
# >> file 把前面命令输出的内容追加(增加)到文件 file 中,如:
ls -al /home >> ./output.txt
ls -al /home/young >> ./output.txt
ls -al
列出的.
和..
为隐藏目录,.
代表当前目录,..
代表父目录。
2.3 cd 切换目录
命令 | 作用 |
---|---|
cd .. |
返回上一级目录 |
cd / |
切换到根目录 |
cd ~ 或者 cd |
切换到当前用户的主目录。普通是 /home/username,超级是 /root |
cd - |
回退到上一次的目录 |
2.4 新建文件(普通文件、目录文件)
-
mkdir /root/1
,新建目录文件 1 ,但是只能在已存在的目录root
下创建新目录 1 。只有加上选项 -p 后,如
mkdir -p /root/1/2/3
,才可以在root
目录下创建多级未存在的目录1/2/3
。 -
touch fileName
新建普通文件 fileName 。
2.5 rm 删除
rm -rf /
从删库到跑路。
选项 | 作用 |
---|---|
-f | force,强制删除。 |
-r | recursively,递归地进入目录执行。rm -rf /home/xiaolong/test.txt 删除 home 目录下的 xiaolong 目录下的 test.txt 文件如 rm -rf /home/xiaolong 删除 home 目录下的 xiaolong 目录及该目录下的所有文件 |
-i | interact,交互式删除。如询问是否删除 [yes] or [no] |
2.6 cp 拷贝(复制+粘贴)
选项 | 作用 |
---|---|
-f | 强制拷贝并替换同名文件 |
-i | 需要替换时交互式替换。如询问是否替换 [yes] or [no] |
-a | 通常在拷贝目录时使用,递归地拷贝目录 |
-r | 递归地执行 |
# 将当前目录的 mjpeg 目录下的所有文件递归地拷贝到当前目录的 socket 目录下
cp -a mjpeg/ socket/
# 将 123.c 文件的内容拷贝到 456.c 文件中
cp -a 123.c 456.c
2.7 mv 移动/重命名
选项 | 作用 |
---|---|
-f | 同名时强制替换 |
-i | 需要替换时交互式替换。如询问是否替换 [yes] or [no] |
# 将 /root/ 目录下的 file 移动到 /home/user1/ 目录下并重命名为 renamedFile
mv /root/file /home/user1/renamedFile
2.8 查找
2.8.1 find
find [目录范围] [选项]
选项 | 作用 |
---|---|
-name <查询方式> |
按照文件名查找指定的文件 |
-user <用户名> |
查找属于指定用户名的所有文件 |
-size <文件大小> |
按照指定的文件大小查找文件 |
# 按照名字在 home 目录下查找 hello.txt文件
find /home -name hello.txt
# 拥有者:查找 opt 目录下,用户名为 young 的文件
find /opt -user young
# 查找整个 linux 系统下大于 200M 的文件
find / -size +200M
# 单位有: G M k(小写的 k )
# +n 大于 n
# -n 小于 n
# n 等于 n
# 查找结果写到文件中
find / -size +200M > ./output.txt
2.8.2 grep
Globally search a Regular Expression and Print,使用正则表达式(Regular Expression)搜索。
管道符|
:表示将前一个命令的处理结果传递给后面的命令处理。通常 grep 会结合管道符一起使用。
选项 | 作用 |
---|---|
-n | number,显示匹配行及行号 |
-i | ignore,忽略字母大小写 |
# 在 hello.txt 文件中查找 yes 所在的行,并显示行号(引号可以省略不写)
cat ./hello.txt | grep -n "yes"
# 或者使用这种写法
grep -n "yes" ./hello.txt
# 前者是接收到 cat 命令的输出结果,在该输出结果中进行过滤
# 后者是直接在 hello.txt 文件中查找过滤
# 在当前目录查找名c含有 .zsh 的目录项
ls -a | grep .zsh
2.9 修改权限、拥有者、所在组
2.9.1 chmod 修改文件权限
change mode
chmod 764 123.txt
# 三组用户对 123.txt 的权限修改为了 7=4+2+1 6=4+2 4=4
# 即 rwxrw-r--
2.9.2 chown 修改文件拥有者
change owner
# 将 test 目录的拥有者由 young 修改为 tom
chown tom test
2.9.3 chgrp 修改文件所在组
change group
# 添加 newgroup 组
groupadd newgroup
# 修改 test 目录所在组为 newgroup 组
chgrp newgroup test
2.9.4 修改用户所在组
# 将用户 zwj 移动到 wudang 组中
usermod -g wudang zwj
2.10 vim 命令
-
一般命令模式
命令行模式下,
:
和/
和?
均可进入一般命令模式。-
退出
:wq
写回并退出、:q
退出且不写回、:!q
强制退出。 -
查找与替换
命令 作用 /word 在光标之下查找 word,再输入 n (意为 next)查找下一个 ?word 在光标之上查找 word,再输入 n 查找下一个 :100,200/word1/word2/g 将第 100 行与第 200 行之间的 word1 替换为 word2 :%s/word1/word2/g 将文件中所有的 word1 替换为 word2。若结尾加上 c (confirm)则会确认是否替换
-
-
命令行模式
-
普通命令
命令 作用 i 进入编辑模式 u undo,撤销 ctrl+r repeat,重做 ctrl+s 僵死状态,往往因为 Windows 中的习惯而造成误按,通过 ctrl+q 解决 # vim 编辑文件时,光标定位到 main.c 的第 3 行 vim +3 main.c
-
复制粘贴
注意:0 表示行首, $ 表示行尾。
命令 作用 yy 复制光标所在行
nyy 复制光标所在行及下面的 n-1 行y0 复制从光标到行首的数据 y$ 复制从光标到行尾的数据 yG 复制从光标所在行到末行的数据
y1G 复制从光标所在行到第 1 行的数据p 粘贴到光标下一行( P 粘贴到光标上一行) -
删除
命令 作用 dd 删除光标所在行
ndd 删除光标所在行及下面的 n-1 行d0 删除光标到行首的文本 d$ 删除光标到行尾的文本,主要用于删除注释 -
定位
命令 作用 G 光标定位到末行 gg 光标定位到首行 n shift + g 光标定位到第 n 行
-
-
编辑模式
按 ESC 进入一般命令模式。
vim ~/.vimrc
在当前用户的主目录上新建 .vimrc 文件配置 vim 环境。
set nu "显示行号
set nonu "不显示行号
2.11 打包与压缩
打包(tar,即tape archive):将多个文件集中到一个文件中,总文件大小并未改变。
压缩(即zip 或 compress):将一个文件通过压缩算法变成一个小文件,以实现在互联网上快速传输。
压缩时,需要先打包再压缩。通过 tar 命令打包,通过 gzip 与 gunzip、 bzip2 与 bunzip2 压缩/解压。
命令格式:tar [主选项 + 辅助选项] 文件
,选项由主选项和辅助选项共同构成。
主选项有如下 5 种,但只能同时使用一个:
选项 | 作用 |
---|---|
-c | create,打包 |
-x | extract,解包 |
-u | update,更新原压缩包中的文件 |
-t | list,查看压缩文档中的内容 |
-r | append,向压缩文档中追加文件 |
辅助选项没有限制,可随意选用:
选项 | 作用 |
---|---|
-z | 使用 gzip 压缩程序进行压缩,后缀为.tar.gz 。注:Linux 中的后缀仅起标识作用,方便观看,没有实际意义。 gzip 压缩的包只能用 gunzip 解压,不能用 bunzip2 解压。 bzip2 同理。 这里的后缀 .tar.gz 的作用是告诉用户该文件是用 tar 命令打包,并且用 gzip 压缩程序压缩过的文件,因此解压时也应使用 tar 打包,通过 gunzip 解压程序解压。 |
-j | 使用 bzip2 压缩程序进行压缩,后缀为.tar.bz2 ,同上。 |
-v | 显示详细的操作过程,通常都加上这个选项。 |
-f | file,指定文件名,必须作为最后一个选项,其后紧跟着文件名,通常都加上这个选项。 |
# 将文件 file1 和 file2 打包成 file.tar,但不压缩
tar -cvf file.tar file1 file2
# 将文件 file1 和 file2 打包,然后用 gzip 程序将其压缩成文件 file.tar.gz
tar -zcvf file.tar.gz file1 file2
# 将文件 file1 和 file2 打包,然后用 bzip2 程序将其压缩成文件 file.tar.bz2
tar -jcvf file.tar.bz2 file1 file2
# 用 gunzip 程序解压文件 file.tar.gz,解压 bizp2 文件时同理
tar zxvf file.tar.gz
将当前目录下的exer
子目录打包然后压缩成exer.tar.gz
文件:
tar -tvf exer.tar.gz
在不解压的情况下查看压缩包的内容:
tar -zxvf exer.tar.gz
将该压缩包解压到当前目录(如果重名,则直接覆盖替换):
-
总结
压缩选项:-zcvf -jcvf
解压选项:-zxvf -jxvf
3. 网络环境配置
DHCP 动态分配 IP 仅限于个人玩玩。服务器的 IP 一般都是要固定下来的,比如百度和京东的服务器的公网 IP 永远都不能改。
# 首先安装网络管理工具(安装后才能使用 ifconfig)
sudo apt-get install net-tools
实际开发中,通过修改/etc/sysconfig/network-scripts/ifcfg-ens33
文件,将虚拟机 IP 配置成静态 IP 。本机如下:
然后执行systemctl restart network.service
即可生效,或者直接重启也可。
IP 随便想一个不冲突的即可,也可使用dhclient
随机分配一个,再将该 IP 设置成静态的。
网关 IP 一般配置成网段的第一个主机,也即192.168.213.1
,但是
可以看到,VMnet8 的 IP 已经占用了192.168.213.1
,因此我这里把网关设置成192.168.213.2
。
vim /etc/hostname
修改主机名,重启生效。
Windows 中ipconfig /displaydns
查看本地 DNS 缓存。
注: 2022 年 1 月 8 日,因为一些其他的原因,我把静态 IP 修改为了 192.168.213.131
。
4. 进程
ps -aux
查看当前所有进程的信息,一般会加上grep
加以过滤
第 1 行是正在运行的进程,第 2 、 3 行是远程连接的进程,第 4 行是执行的 grep 过滤命令的进程。可加上|grep -v grep
反向过滤掉该进程(去除,类似求补集)。
同样的还有ps -ef
,两者作用相同,只是显示的格式风格不同。ps -aux
以 BSD 风格显示,ps -ef
以 System V 风格显示,推荐使用ps -ef
。
1000 号进程的父进程为 1 号进程;1655 号和 1664 号进程的父进程为 1000 号进程;2207 号进程的父进程为 1663 号进程。
另外,还有pstree
以树状显示进程,选项有:
选项 | 作用 |
---|---|
-p | 显示 pid |
-u | 显示该进程的用户 |
# 杀死指定进程号的进程(仅杀死一个进程)
kill [pid]
# 杀死指定指定进程名的进程(杀死与该进程名有关的所有进程)
killall [processname]
僵尸进程、孤儿进程与 init 进程
僵尸进程
任何一个子进程(init 除外)在调用 exit() 退出之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程调用 wait() 或者 waitpid() 处理。这是每个子进程在结束时都要经过的阶段。
如果子进程在 exit() 之后,
-
如果父进程没有来得及 wait() 处理,这时用 ps 命令就能看到子进程的状态是“Z”。
-
如果父进程能及时处理,可能用 ps 就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。
-
如果父进程一直不调用 wait() 或者 waitpid() ,那么子进程的 PCB 就不会释放,其进程号就会一直被占用。此时子进程的状态称为僵死状态,处于僵死状态的进程称为僵尸进程。正常情况下,僵尸进程都立刻被父进程清理了。
系统所能使用的资源是有限的,如果大量的产生僵尸进程,将因为系统资源不足而导致系统不能产生新的进程。
孤儿进程与 init 进程
-
如果父进程在子进程 exit() 之前退出,该子进程便成为了孤儿进程。
-
进程退出后,init 进程(pid 为 1)会扫描所有进程,查看刚刚退出进程是否有子进程还未退出(也就是孤儿进程)。如果有,便会接管该孤儿进程,成为它的父进程。
-
init 进程会循环地 wait() 所有的它接管的孤儿进程,因此被 init 进程接管的进程都不会变成僵尸进程。由于有 init 进程的处理,所以孤儿进程并不会有什么危害。
5. 监控
5.1 进程监控
top 与 ps 的不同之处在于, top 会动态地更新正在运行的进程,默认每 3 秒更新一次(类似 Windows 中的任务管理器),而 ps 则只显示 ps 命令执行的那一刻的进程情况。
介绍一下各个字段的含义:
字段 | 含义 |
---|---|
PR | priority,进程优先级,越小优先级越高 |
NI | nice value,负值的优先级高于正值,0 表示优先级不能改变。其与 priority 关系密切,但是这里我就不深究了。 |
VIRT | virtual memory size,进程占用的虚拟内存(KiB) |
RES | resident memory size,进程占用的物理内存(不含 swap 交换区)(KiB) |
SHR | shared memory size,进程可用的共享内存量 注:并非会全部共享出去,仅仅反映了可能与其他进程共享的内存大小 |
S | status,进程状态。 R,running S,sleeping Z,zombie |
%CPU | CPU 占用率 |
%MEM | 内存占用率 |
TIME+ | 进程启动后占用的总的 CPU 时间 |
COMMAND | 启动该进程的命令或程序 |
进入动态页面后,可通过按键实现一些功能:
键 | 功能 |
---|---|
P | 以 CPU 占用率对进程排序 |
M | 以内存占用率对进程排序 |
u | 输入用户名后,监控该用户的进程 |
k | 输入 pid 后,杀死该进程 |
q | 退出 |
top -p 1
监控进程号 1 的进程。
5.2 网络监控
netstat,network status
选项 | 作用 |
---|---|
-a | 全部开放的端口 |
-n | numeric,主机、端口、用户名以数字形式显示 |
-p | 显示哪个进程在调用该端口,即显示端口的守护进程 |
我的电脑用 Xshell 连接到了 Linux 虚拟机,可以看到,有 2 个进程通过不同的端口分别与虚拟机的 22 端口都建立了连接。
由此可见,虚拟机与 VMnet8 连接, VMnet8 再与宿主机的网卡连接从而实现上网。
6. 服务管理
CentOS 7 之前的通过 service 管理服务,CentOS 7之后,服务由 systemctl 管理,只有少部分服务也可由 service 管理。
# 查看非本地服务
chk
# 查看所有的系统服务
systemctl list-unit-files
# 查看特定服务的状态
systemctl list-unit-files | grep [服务名]
# 终止网络服务
systemctl stop network.service
# 启动网络服务
systemctl start network.service
# 重启网络服务
systemctl restart network.service
# .service 均可省略
# 获取当前用户级别: graphical.target 为图形化界面级别(5 级)、 multi-user.target 为多用户级别(3 级)……,基本上只用 3 级。
systemctl get-default
# 将用户级别设置为 multi-user.target
systemctl set-default multi-user.target
# 设置成开机自启动
systemctl enable [服务名]
# 关闭开机自启动
systemctl disable [服务名]
# 查询该服务是否开机自启动
systemctl is-enabled [服务名]
# 查询该服务当前的状态
systemctl status [服务名]
# 查询该服务开机启动状态
systemctl list-unit-files | grep [服务名]
可在/usr/lib/systemd/system
中查找 .service 后缀的文件以查找服务名:
# 防火墙命令
firewall-cmd --permanent --add-port=端口号/协议 # 打开端口
firewall-cmd --permanent --remove-port=端口号/协议 # 关闭端口
firewall-cmd --reload # 重载生效
firewall-cmd --permanent --query-port=端口号/协议 # 查询端口是否开放
netstat -anp
查询端口的协议:
可以看到,虽然未 reload 仍然可以生效,但是还是建议开放(或关闭)端口后, reload 重载生效。
7. Shell 脚本(Scripts)
历史背景:shell 有多种,第一个流行的 shell 是由 Steven Bourne 开发的,为了纪念他所以就称为 Bourne shell ,简称 sh ,搭载在 1977 年底发布的经典的 UNIX v7 上。
Linux 目前使用的 shell 版本称之为 Bourne Again SHell ,简称 bash ,是在1989年对 sh 的重写版(或者叫“增强版”),替代了 sh (类似 vim 之于 vi )。
规定脚本首行写上#!/bin/bash
加以标识(不些也行,这只是一个说明)。运行脚本的两种方式:
- 通过 shell 脚本解析器运行脚本
sh /root/test/test.sh
( Linux 的 shell 解析器是 bash )。 - 编写的脚本默认是没有执行权限的,哪怕是拥有者也没有。需先给脚本添加执行权限
chmod u+x /root/test/test.sh
后,才能直接运行脚本/root/test/test.sh
。
2019 年后,macOS 的终端默认使用的 shell 由 bash 改为了 zsh ,zsh 也是一种 shell ,它对 bash 做了大量改进,同时还加入了一些新的特性,是一个现代化的 shell 。
可以下载 oh-my-zsh 插件对 zsh 进行扩展从而使得终端界面更加美观。
7.1 变量
$VAR 表示取出变量 VAR 的值。变量可以是系统的环境变量(或称全局变量,如 HOME 、 PATH ),也可以是用户自定义变量,规定变量名大写。
# 单行注释
:<<!
多行注释
!
# 赋值语句中不能有空格
A=100
# $A 取出变量的值
echo "A=$A"
# 撤销变量
unset A
echo "A=$A"
# 静态变量,也叫只读变量,不能被撤销
readonly B=200
echo "B=$B"
unset B
echo "B=$B"
# 将命令或函数的返回值赋值给变量。 date 为日期函数
C=$(date)
# 或者 C=`date`
echo "C=$C"
-
位置参数变量
类似 C 语言中
int main(char argc char *argv[])
的 argc 与 argv ,在运行时传入参数。#!/bin/bash # $0 代表 ./test.sh 命令本身,$1 ~ $9 为第 1~9 个参数 echo "0=$0 1=$1 2=$2" # $* 代表命令行中的所有参数,看成一个整体 echo "所有的参数=$*" # $@ 代表命令行中的所有参数,看成多个个体 echo "$@" # $# 代表命令行中参数的个数 echo "共有 $# 个参数" # 运行脚本时从命令行获取参数 100 和 200 ./test.sh 100 200
-
运算符
VAR=$[(2+3)*4] echo "VAR=$[(2+3)*4]" echo "VAR=$VAR"
VAR=$[$1+$2] echo "$VAR"
7.2 流程控制
-
条件判断
# = 比较字符串是否相等 # 整数比较: # -lt 小于 # -gt 大于 # -eq 等于 # -le 小于等于 # -ge 大于等于 # -ne 不等于 # 文件类型判断: # -f file,文件存在且是普通文件 # -e exist,文件存在 # -d directory,文件存在且是目录
# 注意空格,shell 脚本的空格十分严格 # if空格[空格condition空格] # 判断条件为空时:if [空格] if [ "ok" = "ok" ] then echo "ok equals ok" # finish 类似花括弧 fi if [ 23 -ge 22 ] then echo "23 greater than 22" fi if [ -f /root/test/test.sh ] then echo "test.sh existed" fi
if [ $1 -lt 425 ] then echo "failed" elif [ $1 -lt 80 ] then echo "passed" elif [ $1 -lt 90 ] then echo "passed, and great" elif [ $1 -lt 100 ] then echo "passed, and awesome" elif [ $1 -eq 100 ] then echo "oh my god" fi
# case [变量] in ==> Java 中的 switch(变量) case $1 in "1") echo "一";; "2") echo "二";; "3") echo"三";; # 默认分支 *) *) echo "找不到";; # 以反 case 的 esac 结束,类似花括弧 esac
-
循环
# for 循环 # 若变量的值属于 $* ,执行循环体 echo "*:" for i in "$*" do # $* 将全部参数看成一个整体 echo "num is $i" done echo "@:" for i in "$@" do # $@ 将全部参数看成各自的个体 echo "num is $i" done
# for 循环的另一种写法 SUM=0 # 这里的判断只能用 < <= > >= 等运算符比较,不能用 -le 等条件判断式 for((i=$1; i<=$2; i++)) do SUM=$[$SUM+$i] done echo "SUM=$SUM"
# while 循环 SUM=0 i=0 while [ $i -le $1 ] do SUM=$[$SUM+$i] # 自增 i=$[$i+1] done echo "SUM=$SUM"
7.3 read 读取控制台输入
# 从控制台输入一个数,类似 C 语言的 scanf 函数
read -p "输入一个数NUM1=" NUM1
echo "NUM1=$NUM1"
# 从控制台输入一个数,仅监听 10 秒,超过 10 秒自动结束
read -t 10 -p "输入一个数NUM2=" NUM2
echo "NUM2=$NUM2"
7.4 函数
# 系统函数:basename 、 dirname,以 basename 为例, dirname 同理。
# 函数的返回值用 $() 接收
# $(basename $0 .sh) 会把文件名的后缀 .sh 去掉,
# 即 NAME 为 add 和 multiply
NAME=$(basename $0)
if [ $NAME = "add.sh" ]
then
RESULT=$[$1 + $2]
elif [ $NAME = "multiply.sh" ]
then
RESULT=$[$1 * $2]
fi
echo The calculated value is $RESULT
# 自定义函数
function getSum(){
SUM=$[$arg1+$arg2]
echo "SUM=$SUM"
}
read -p "输入参数 arg1=" arg1
read -p "输入参数 arg2=" arg2
# 调用函数
getSum $arg1 $arg2
8. 日志
记录系统事件,如用户登录信息、系统启动信息(何时启动、启动耗时等)、系统安全信息等……
日志位于
/var/log/
目录。
常见日志:
日志文件 | 常见日志 |
---|---|
/var/log/boot.log | 系统启动日志 |
/var/log/cron | 系统定时任务相关的日志 |
/var/log/lastlog | 记录所有用户最后一次登录的日志,只能使用lastlog 查看内容,cat 查看会乱码 |
/var//log/maillog | 记录邮件信息 |
/var/log/message | 记录系统大部分重要信息。当系统出现问题,首先检查这个日志 |
/var/log/secure | 记录验证和授权相关的信息。 如:涉及账户和密码的程序( ssh 远程登录, su 切换用户, sudo 授权……)、添加用户、修改用户密码等…… |
日志服务由rsyslogd
服务管理,类似于mysqld
之于mysql
。日志的配置信息位于/etc/rsyslog.conf
。在此文件中添加自定义的日志配置。
日志轮替策略:定期地更新日志,避免日志文件过大、存储很久之前的无用日志。
/etc/logrotate.conf
设置全局日志(对所有日志文件都生效)的轮替策略。
/etc/logrotate.d
目录下存放对单独的日志文件设置的轮替策略。