Linux 复习笔记

  仅用做复习之用。

文件操作

列表详情

命令 说明
ls 显示文件列表
ls -l 显示文件长列表
ls my_script 过滤输出列表

文件处理

  

命令 说明
touch fileName 创建空文件
cp source destination 复制文件(加-R复制所有)
mv source dest 移动/重命名 文件
rm -rf file 删除文件(加-rf删除所有)
tar -cvf test.tar /test 压缩文件
tar -xvf test 解压文件
mkdir New_Dir 创建新目录
rmdir New_Dir 删除新目录(不推荐)
ln source_file dest_file 链接文件(硬)
ln -s source_file dest_file 链接文件(软)

扩展——文本替换

1
2
# vim 下文本替换
%s/源字符串/目的字符串/g

内容查阅

  文件内容查阅的相关命令见下表:

命令 说明
file 查看文件类型
cat 由第一行开始显示文件内容
tac 从最后一行开始显示, cat 的反写
more 一页一页的显示文件内容
less 与 more 类似,但其可以往前翻页
head 只看头几行
tail 只看尾巴几行
nl 显示的时候,顺道输出行号
od 以二进制的方式读取文件内容

位置查找

脚本文件搜寻

  通过which可以寻找到指令的完整文件名放在哪里。

文件搜寻

  文件的搜寻主要为以下 3 个命令:

  • whereis:只能查找系统中某些特定目录(whereis -l查看)底下的文件
  • locate:利用数据库来查找文件(新创建的文件需通过updatedb更新到数据库)
  • find:全局扫描,如find /etc -name passwd

进程与磁盘监测

进程监测

命令 说明
ps 显示当前用户所有进程(简略)
ps -ef 显示所有进程及详细情况

  -e参数指定显示所有运行在系统上的进程;-f参数则扩展了输出,这些扩展的列包含了有用的信息。

  • UID:启动这些进程的用户
  • PID:进程 ID
  • PPID:父进程 ID(若该进程由另一个进程启动)
  • C:进程生命周期中的 CPU 利用率
  • STIME:进程启动时的系统时间
  • TTY:进程启动时的终端设备
  • TIME:运行进程需要的累计 CPU 时间
  • CMD:启动的程序名称

  若想要获得更多 的信息,可采用-l参数,它会产生一个长格式输出。

  使用-l参数后多出以下列:

  • F:内核分配给进程的系统标记
  • S:进程状态(O:正在运行;S:在休眠;R:可运行,正等待运行;Z:僵化(进程已结束但父进程已不存在);T:停止)
  • PRI:进程的优先级(越大的数字代表越低的优先级)
  • NI:谦让度值用来参与决定优先级
  • ADDR:进程的内存地址
  • SZ:若进程被换出,所需交换空间的大致大小
  • WCHAN:进程休眠的内核函数的地址

磁盘监测

命令 说明
lsblk 显示所有磁盘及分区情况
blkid 列出文件系统与装置的 UUID
mkfs.ext4 [disk] 格式化指定磁盘(建立 ext4 文件系统)
mount [disk] [path] 磁盘挂载
umount [] [] 卸载磁盘
df -h 查看所有已挂载磁盘的使用情况
df -T 查看所有磁盘使用的文件类型
du -h 显示特定目录(默认当前目录)所有文件磁盘占用情况
du -sh * 仅显示当前目录下各文件磁盘占用情况

缓存清除

仅清除页面缓存(PageCache)

1
2
# sync; echo 1 > /proc/sys/vm/drop_caches      
sudo sh -c "echo 1 > /proc/sys/vm/drop_caches"

清除目录项和 inode

1
2
# sync; echo 2 > /proc/sys/vm/drop_caches 
sudo sh -c "echo 2 > /proc/sys/vm/drop_caches"

清除页面缓存,目录项和 inode

1
2
# sync; echo 3 > /proc/sys/vm/drop_caches 
sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"

环境变量

命令 说明
envprintenv 查看全局环境变量
printenv [envName] 查看指定的环境变量
echo $envName 查看指定的环境变量
export envName=111 设置全局环境变量
unset envName 删除环境变量

文件权限

什么是文件权限?

  由于 Linux 是个多人多任务的系统,因此存在多人同时使用一个主机工作的情况。
  为了考虑每个人的隐私权及其喜好的工作环境,设计者思考出一个绝妙的点子——对同一个文件,可以面向不同的用户,不同用户各自对同一文件拥有的权限却各不相同

文件权限的划分

  这些权限可以划分为:

  • r(read):可读
  • w(write):可写
  • x(execute):可执行

注意哦:对文件(如文本文件、二进制文件)或目录而言,rwx权限作用是不同滴,详见下表:

类别\权限 r w x
文件 可读取文本内容 可编辑、新增或修改该文件内容(但不能删除该文件) 可执行该文件
目录 可查询目录中文件列表 修改目录及其中文件 可进入该目录

  其中,对目录w操作的修改目录及其中文件指的是,在目录中:

  • 可创建新的文件或目录
  • 可删除已经存在的文件与目录(不论该文件的权限为何)
  • 可重命名其中的文件或目录;
  • 可移动该目录内的文件或目录

注意哦:当对一个文件具有 w 权限时,具有写入/编辑/新增/修改文件内容的权限, 却无删除该文件本身的权限!对于文件的rwx来说, 主要都是针对『文件的内容』而言,与文件的存在与否没有关系喔!因为文件记录的是实际的数据哦!

  用命令来具体了解一下:

1
2
3
4
5
6
7
8
9
[git@wking ~]$ ls -al
total 10
drwx------ 4 git git 4096 Sep 2 09:22 .
drwxr-xr-x. 3 root root 4096 Sep 2 09:51 ..
-rw------- 1 git git 1587 Sep 2 09:22 .bash_history
-rw-r--r-- 1 git git 18 Dec 7 2016 .bash_logout
-rw-r--r-- 1 git git 193 Dec 7 2016 .bash_profile
[ 1 ] [2] [3] [4] [5] [6] [ 7 ]
[ 权限 ] [连结][拥有者][群组][文件大小] [修改日期] [ 文件名 ]

  相同文件可以面向不同的用户,用户对不同文件的权限也不同。

文件面向的用户

  文件面向的用户,具体可以划分为:

  • 文件拥有者—— User
  • 群组—— Group
  • 其他人—— Others

文件拥有者—— User

  举个栗子:当你将小姐姐送的情书转存成文件,放在家目录之后,你总不希望被其他人看见吧?
  此时,就可把文件设定成只有文件拥有者,即只有爸爸我一个人拥有查看与修改该文件的权限

群组—— Group

  群组最重要的作用就是用于团队开发
  举个栗子:假设有个项目需要根据 2 个竞争小组的报告作出选择:

  • 第一个小组 A,里面的成员有 A1、A2、A3
  • 第二个小组 B,里面的成员有 B1、B2、B3 、B4

   这两个小组之间是有竞争性质的,但却要缴交同一份报告。
  其中,每组的组员之间必须要能够互相修改对方的数据, 但是 A 组与 B 组的组员则不能互相看到对方组的文件,此时该怎么做呢?
  在 Linux 中经简易的文件权限设定,就能限制非自己组的人不能够阅览内容,且可以让组间成员互相修改数据。
  同时,若自己还有私人隐密的文件,仍然可以设定为其他人禁止查看。

  另外,如果 pm 这个用户是 A B 两组的项目经理, 他想要同时观察两者的进度,因此需要能进入这两个群组的权限时,可以设定 pm 用户同时加入 A 与 B 群组。

  换而言之,每个用户都可以加入多个组。

其他人—— Others

  还是拿群组的例子,项目的甲方不关注项目是如何开发的,只关注开发的进展情况,就可以将其权限设置为其他人啦,让甲方只拥有读取项目进展的权限即可。

文件权限的修改

  文件权限的修改命令为以下 3 个:

命令 说明 示例
chown 改变文件拥有者 chown wk a.txt
亦可同时改变群组 chown wk:wkgroup a.txt
chgrp 改变文件所属群组 chgrp wkgroup a.txt
chmod 改变文件的权限:SUID,、SGID、 SBIT 等特性 chmod 744 start.sh
chmod a+x start.sh

小提示:若为目录,以上命令加上-R参数,则修改可作用该目录下所有文件及目录

用户管理

新增用户

  使用useradd命令可以新增一个用户且可同时指定(多个)群组:

1
useradd [-u UID] [-g 初始群组] [-G 次要群组]

  举个栗子,下面的代码建立了一个 wk 用户,其属于 wkgroup 群组:

1
useradd -g wkgroup wk

passwd 命令

  那么我们如何登录这个用户呢?
  首先肯定是要给该用户设置密码的,使用passwd命令即可:

1
passwd wk

  之后输入 2 次你想设置的密码即可。
注意哦:若passwd命令后面没有加用户,则直接修改当前用户的密码:

  passwd命令不仅可以修改密码,还可以选择以下参数:

  • -l:锁定当前用户,即禁用用户
  • -u:解锁当前用户
  • -d:删除当前用户密码
  • -f:强迫当前用户下次登录时修改密码
1
passwd [-ludf] 用户名

修改用户

  若在新增用户时加入了错误的设定数据或者只是单纯地想修改的配置。
  此时,可以使用usermod进行用户相关数据的微调!

1
2
3
4
5
6
7
8
9
10
11
12
[root@wk ~]# usermod [-cdegGlsuLU] username
选项与参数:
-c :后面接用户的说明,即 /etc/passwd 第五栏的说明栏,可以加入一些用户的说明
-d :后面接用户的家目录,即修改 /etc/passwd 的第六栏;
-e :后面接日期,格式是 YYYY-MM-DD 也就是在 /etc/shadow 内的第八个字段数据啦! -f :后面接天数,为 shadow 的第七字段。
-g :后面接初始群组,修改 /etc/passwd 的第四个字段,亦即是 GID 的字段!
-G :后面接次要群组,修改这个使用者能够支持的群组,修改的是 /etc/group 啰~
-a :与 -G 合用,可『增加次要群组的支持』而非『设定』喔!
-l :后面接用户名称。亦即是修改用户名称, /etc/passwd 的第一栏!
-s :后面接 Shell 的实际文件,例如 /bin/bash 或 /bin/csh 等等。
-u :后面接 UID 数字啦!即 /etc/passwd 第三栏的资料;
-L :暂时将用户的密码冻结,让他无法登入。其实仅改 /etc/shadow 的密码栏。

删除用户

  若想删除用户的相关数据,而用户的数据有:

  • 用户用户/密码相关参数:/etc/passwd/etc/shadow
  • 使用者群组相关参数:/etc/group/etc/gshadow
  • 用户个人文件数据:/home/username/var/spool/mail/username..

  只需使用userdel命令即可:

1
2
[root@wk ~]# userdel [-r] username 
-r :连同用户的家目录也一起删除

查看用户列表

  新建用户完成之后,如何查看用户呢?

  我们可以使用如下命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cat /etc/passwd

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
wk:x:1000:1000::/home/wk:/bin/bash

  上诉命令缺点就是列出来的信息过多,如果仅关注用户的话,可以这么做:

1
2
3
4
5
cat /etc/passwd | grep -v nologin|grep -v halt|grep -v shutdown|awk -F":" '{ print $1"|"$3"|"$4 }'|more

root|0|0
sync|5|0
wk|1000|1000

用户所属群组

  虽然我们可以在创建用户的时候指定群组,也可在创建完成之后修改群组,但 Linux 有更具体的命令来操作。
  基本上, 群组的内容都与这两个文件有关:

  • /etc/group
  • /etc/gshadow

新增群组

1
2
3
4
5
6
7
8
9
10
[root@wk ~]# groupadd [-g gid] [-r] 组名
选项与参数:
-g :后面接某个特定的 GID ,用来直接给予某个 GID ~
-r :建立系统群组啦!与 /etc/login.defs 内的 GID_MIN 有关。
范例一:新建一个群组,名称为 group1
[root@wk ~]# groupadd wkgroup
[root@wk ~]# grep wkgroup /etc/group /etc/gshadow
/etc/group:group1:x:1503:
/etc/gshadow:group1:!::
# 群组的 GID 也是会由 1000 以上最大 GID+1 来决定!

修改群组

  跟 usermod 类似的,groupmod指令仅是在进行 group 相关参数的修改而已:

1
2
3
4
5
6
7
8
9
10
[root@wk ~]# groupmod [-g gid] [-n group_name] 群组名 

选项与参数说明:
-g :修改既有的 GID 数字; -n :修改既有的组名

范例一:将刚刚上个指令建立的 wkgroup 名称改为 mygroup , GID 为 201
[root@wk ~]# groupmod -g 201 -n mygroup wkgroup
[root@wk ~]# grep mygroup /etc/group /etc/gshadow
/etc/group:mygroup:x:201:
/etc/gshadow:mygroup:!::

删除群组

1
2
3
4
[root@wk ~]# groupdel [groupname] 

范例一:将刚刚的 mygroup 删除!
[root@wk ~]# groupdel mygroup

  注意哦,若要删除一个还存在用户的群组,则无法删除,比如:

1
2
[root@wk ~]# groupdel we
groupdel: cannot remove the primary group of user 'we'

扩展:用户 sudo 命令免密码

  当前用户不是 root 时,有些操作会因为权限不够而被拒绝,需要 sudo 才可以完成。但是每次 sudo 都需要输入密码,非常麻烦。

  那么,如何让 sudo 命令不需要验证密码就可以执行呢?

  修改一个配置文件即可。

1
sudo vim /etc/sudoers

  可以看到有这么一段内容:

1
2
3
4
5
6
7
##
## User privilege specification
##
root ALL=(ALL) ALL
admin ALL=(ALL)

%wheel ALL=(ALL) ALL

  这两行是允许 root 用户和 admin 用户组的所有用户,在所有主机上执行所有命令,当然是需要 passwd 的。

  若想要免密码,可以添加 NOPASSWD:ALL

  例如给 admin 用户添加免密码使用sudo命令,则添加:

1
2
3
admin ALL=(ALL) NOPASSWD:ALL
# 组免密
%admin ALL=(ALL:ALL) NOPASSWD:ALL

  最后 :wq! 强制保存退出即可,以后 sudo 就不再需要密码验证了。

  如果打开终端执行sudo命令发现仍然需要密码,

  可能是刚添加的语句被后续%wheel ALL=(ALL) ALL这句覆盖了。

  id admin查看admin是否在wheel组,发现果然存在:

1
2
id admin
uid=1000(admin) gid=1000(admin) 组=1000(admin),10(wheel),981(docker)

  那么我们把相关命令放%wheel ALL=(ALL) ALL,修改配置文件,保存即可

1
2
3
4
5
%wheel  ALL=(ALL)       ALL

admin ALL=(ALL) NOPASSWD:ALL
# 组免密
%admin ALL=(ALL:ALL) NOPASSWD:ALL

软件安装

  在 Linux 的早期,安装软件是一件痛苦的事。幸好 Linux 开发人员已经通过把软件打包成更易于安装的预编译包,我们的生活因此舒坦了一些。

  因此,在 Linux 上,一般通过各种包管理系统(package management system,即 PMS)或者命令行工具用来进行软件的安装、管理和删除。

包管理基础

  在各种主流的 Linux发行版上,均采用了某种形式的包管理系统(PMS)来控制软件和库的安装。
  PMS 会利用一个数据库来记录各种相关内容,比如:

  • Linux 系统上已安装了什么软件包;
  • 每个包安装了什么文件;
  • 每个已安装软件包的版本

  对于软件包而言,一般会存储在专门的服务器(这些服务器被称为 repository,即仓库)上,因此可以利用本地 Linux 系统上的 PMS 工具通过互联网访问它,用 PMS 工具搜索新的软件包,或者是更新系统上已安装软件包。
  由于软件包通常会依赖其他的包,为了让前者能够正常运行,被依赖的包必须提前安装在系统中。 那么,PMS 工具将会检测这些依赖关系,并在安装需要的包之前先安装好所有额外的软件包。

  PMS 的不足之处在于目前还没有统一的标准工具,因此 PMS 工具及相关命令在不同的 Linux 发行版上有很大的不同。
  目前,Linux 中广泛使用的两种主要的 PMS 基础工具是 dpkg 和 rpm。

  • dpkg:基于 Debian 的发行版(如 Ubuntu 和 Linux Mint)使用的是 dpkg 命令,这些发行版的 PMS 工具也是以该命令为基础的。dpkg 会直接和 Linux 系统上的 PMS 交互,用来安装、管理和删除软件包。
  • rpm:基于 RedHat 的发行版(如 Fedora、openSUSE 及 Mandriva)使用的则是 rpm 命令,该命令是其 PMS 的底层基础。类似于 dpkg 命令,rpm 命令能够列出已安装包、安装新包和删除已有软件。

  注意,这两个命令是它们各自 PMS 的核心,并非全部的 PMS。许多使用 dpkg 或 rpm 命令的 Linux 发行版都有各自基于这些命令的特定 PMS 工具,这些工具能够助你事半功倍。

基于 RedHat 发行版的包管理工具

  基于 Red Hat 系统常见的可用包管理工具有以下三种:

  • yum:在 Red Hat 和 Fedora 中使用
  • urpm:在 Mandriva 中使用
  • zypper:在 openSUSE 中使用

  以上工具都基于 rpm 命令行工具,它们的区别简单来讲:

  • rpm 只能安装已经下载到本地机器上的 rpm 包
  • yum 能在线下载并安装 rpm 包,能更新系统,且还能自动处理包与包之间的依赖问题

  由于yum更为常用,此处只介绍它:

命令 说明
yum list installed 列出系统上已安装的包
yum install package_name 安装指定软件
yum localinstall package_name.rpm 手动下载 rpm 安装文件并用 yum 安装
yum list updates 列出所有已安装包的可用更新
yum update 对更新列表中的所有包进行更新
yum update package_name 更新指定包
yum remove package_name 只删除软件包而保留配置文件和数据文件
yum erase package_name 删除软件和它所有的文件
yum clean all 处理损坏的包依赖关系
yum repolist 查看仓库

高级命令

awk

  awk 是一个非常棒的数据处理工具!相较于 sed 常常作用于一整个行的处理, awk 则比较倾向于一行当中分成数个『字段』来处理。
  因此,awk 相当的适合处理小型的数据!

基本使用

  awk 的语法是这样的:

1
2
3
awk 'option_one {active_one} option_two {active_two} ...' filename
# 常见语法
awk 'option {active}' filename

  下面为一个常见的示例:

1
2
3
4
5
[root@wking ~]# ps -ef | awk '{print $1 "\t" $2 "\t" $3}'
UID PID PPID
root 1 0
root 2 0
mysql 5591 1

  awk 命令透过 print 的功能将字段数据列出来,在 awk 的大括号内,每一行的每个字段都是有变量名称的,那就 是 $1, $2… 等变量名称($0 代表所有列)。而字段的分隔则以水平制表符(\\t)来隔开。
  由此可知, 刚刚上面五行当中,整个 awk 的处理流程是:

  • ① 读入第一行,并将第一行的资料填入 $0, $1, $2…. 等变数当中;
  • ② 依据 “条件类型” (option)的限制,判断是否需要进行后面的 “动作”(active);
  • ③ 做完所有的动作与条件类型
  • ④ 若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止

  因为不论哪一行我都要处理,因此,就不需要有 “条件类型” 的限制!

  经过这样的步骤,你会晓得, awk 是『以行为一次处理的单位』, 而『以字段为最小的处理单位』。
  那么 awk 怎么知道我到底这个数据有几行?又有几栏呢?这就需要 awk 的内建变量的帮忙啦~

变量名称 代表意义
NF 每一行$0 拥有的字段总数
NR 目前 awk 所处理的是『第几行』数据
FS 目前的分隔字符,默认是空格键

  继续以上面的例子,现在我们只想要看到某一行的数据,那么可以这么做:

1
ps -ef | awk 'NR==3 {print $1 "\t" $2 "\t" $3}'

  现在输出的就只有第三行的数据啦!

时间同步

1
2
3
4
5
6
# 下载时间同步服务
yum install ntp
# 与上海时间进行同步
ntpdate -u ntp.api.bz
# 选择时区
tzselect
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
# 过程说明
Please identify a location so that time zone rules can be set correctly.
Please select a continent or ocean.
1) Africa
2) Americas
3) Antarctica
4) Arctic Ocean
5) Asia
6) Atlantic Ocean
7) Australia
8) Europe
9) Indian Ocean
10) Pacific Ocean
11) none - I want to specify the time zone using the Posix TZ format.
#? 5
Please select a country.
1) Afghanistan 18) Israel 35) Palestine
2) Armenia 19) Japan 36) Philippines
3) Azerbaijan 20) Jordan 37) Qatar
4) Bahrain 21) Kazakhstan 38) Russia
5) Bangladesh 22) Korea (North) 39) Saudi Arabia
6) Bhutan 23) Korea (South) 40) Singapore
7) Brunei 24) Kuwait 41) Sri Lanka
8) Cambodia 25) Kyrgyzstan 42) Syria
9) China 26) Laos 43) Taiwan
10) Cyprus 27) Lebanon 44) Tajikistan
11) East Timor 28) Macau 45) Thailand
12) Georgia 29) Malaysia 46) Turkmenistan
13) Hong Kong 30) Mongolia 47) United Arab Emirates
14) India 31) Myanmar (Burma) 48) Uzbekistan
15) Indonesia 32) Nepal 49) Vietnam
16) Iran 33) Oman 50) Yemen
17) Iraq 34) Pakistan
#? 9
Please select one of the following time zone regions.
1) Beijing Time
2) Xinjiang Time
#? 1

The following information has been given:

China
Beijing Time

Therefore TZ='Asia/Shanghai' will be used.
Local time is now: Wed Mar 23 22:06:00 CST 2022.
Universal Time is now: Wed Mar 23 14:06:00 UTC 2022.
Is the above information OK?
1) Yes
2) No
#? 1

You can make this change permanent for yourself by appending the line
TZ='Asia/Shanghai'; export TZ
to the file '.profile' in your home directory; then log out and log in again.

Here is that TZ value again, this time on standard output so that you
can use the /usr/bin/tzselect command in shell scripts:
Asia/Shanghai
1
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

参考

  • [1] 蔡德明. 鸟哥的 Linux 私房菜 [M]. 人民邮电出版社,2010
  • [2] Richard Blum & Christine Bresnahan. Linux 命令行与 shell 脚本编程大全(第 3 版)[M]. 人民邮电出版社,2016
0%