Linux复习笔记
常识说明
目录结构
Linux以树型结构管理文件,其最上层文件夹为 /
,也就是根目录。
如图所示,图中展示了一部分文件夹的结构:
所有的文件夹都属于根目录的子文件夹。
安装好系统后,根目录会挂载到一个分区上,此时系统下的所有文件都将存在于该分区中。但若将另一个分区挂载到/home目录上,那么,home目录的文件将存在于这个新分区中,也就是从原来的分区中脱离出来。但是,从目录的角度上说,home目录依然是根分区的子目录,只不过,其中文件所存在的分区将和根目录中其他文件和文件夹存在于不同的分区中。
主目录
通常,用户的主目录存在于/home下的以用户名为名称的文件夹中,比如test用户的主目录为/home/test。主目录通常也可以用 ~
表示,例如: cd ~
就是进入当前用户的主目录。
因此,进入test用户主目录有以下几种方式:
Shell Session
cd
cd ~
cd $HOME
cd /home/test
第三行中的 $HOME
意思是读取HOME这个环境变量,通常情况下,当用户登录后,HOME变量的内容会变成当前用户的主目录。
当前目录
打开终端时,一般默认都会在主目录打开,此时会显示一个 ~
,可以使用 cd
切换到其他目录或者切换回主目录。
相对路径
这里的“相对”指的是相对当前目录的位置。
例如:当前目录为 /home/test
,当你使用cd进入上层目录时,就可以使用命令 cd ..
。这里的 ..
表示相对当前目录的上级目录。(一个点 .
表示当前目录。)
假如当前目录为 ~
使用相对路径进入 /usr
目录,命令为:
Shell Session
cd …/…/usr
绝对路径
这里的 “绝对”意思是,和当前目录所在位置无关,直接从根目录开始表示路径。
例如:主目录的位置是 /home/test
,这个路径就是绝对路径,因为他是从根目录开始表示的。
环境变量
顾名思义,环境变量就是在当前系统环境下所存在的变量,其中的变量可能影响系统的一些机制,充分了解环境变量十分有帮助。
查看
要查看当前系统环境下有哪些环境变量,可以使用 env
命令,它将以 key=value
的形式展示当前可用的所有环境变量。比如 PATH
环境变量。
读取
在变量名前添加一个 $
就表示读取这个环境变量的值,比如:
Shell Session
echo 当前用户的主目录为$HOME
输出结果是:
Shell Session
当前用户的主目录为/home/maicss
有时也会将变量名用大括号括起来,例如 ${HOME}
,大括号的作用主要是作为一个边界。防止认不出变量名是哪部分,这个是bash的语法,会在脚本那里详细写到。
设置
设置环境变量可以用 export
命令。例如:
Shell Session
export NAME=maicss
echo $NAME
这时会输出:
Shell Session
maicss
通常想要永久的设置环境变量,可以将上述export命令写到 ~/.bashrc
脚本的末尾。
命令
命令本质上就是一个个的软件或脚本,这些软件或脚本的名称就是命令。命令和环境变量 PATH
有密切的关系。可以先使用 echo $PATH
查看该环境变量的值:
Plain Text
/home/maicss/.local/bin:/home/maicss/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin
在结果中,将存在几个文件夹路径,以英文冒号隔开,命令就存在于这些文件夹中。如果你想刨根问底,可以使用 whereis
命令,例如要查找常用的 cd
命令存在于哪里:
Shell Session
whereis cd
结果应该是:
Plain Text
cd: /usr/bin/cd /usr/share/man/man1/cd.1.gz /usr/share/man/man1p/cd.1p.gz
可以看到,这个命令在/usr/bin/cd中。
若想了解更详细的关于PATH环境变量的内容,可以访问我的博客:https://www.cnblogs.com/maicss/p/14616672.html
软链接和硬链接
软链接也叫符号链接,类似Windows下的快捷方式,当源文件或文件夹删除时,对应的软链接将失效。而硬链接相反,硬链接和其目标文件是有相同地位的,当删除源文件时,为其创建的硬链接还存在并且可用,那文件仍然不算被删除,仅当删除文件和所有的硬链接时,文件才算被删除。
在当前目录下,为 a.txt
创建软链接 b.txt
命令为:
Shell Session
ln -s a.txt b.txt
创建硬链接的命令是:
Shell Session
ln a.txt b.txt
也就是说,ln命令默认创建硬链接,加上 -s
表示令其创建软链接。
磁盘和文件操作
想要使用一块新的磁盘,要依次进行分区、格式化、挂载、权限配置,下面逐个介绍。
分区
想要对磁盘进行分区,要使用的命令是fdisk。这个命令可以实现查看磁盘分区信息、对磁盘和分区进行修改等操作。
找到想要进行分区的磁盘
输入命令
Shell Session
lsblk
输出如下
Plain Text
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 30G 0 disk
├─sda1 8:1 0 300M 0 part /boot/efi
└─sda2 8:2 0 29.7G 0 part /
sdb 8:16 0 8G 0 disk
上边的输出中现实我有两个磁盘,一个是 sda
,另一个是 sdb
。其中sda
有2个分区,其中分区2也就是 sda2
挂载到了根目录。磁盘 sdb
没有分区,总大小为8G。我们要为 sdb
进行分区。
开始分区
- 输入命令
Shell Session
sudo fdisk /dev/sdb
回车后输入密码,然后会打开分区工具。
此时,最后一行应当显示以下内容:
Plain Text
Command (m for help):
此时,闪烁的光标应当在冒号后边。
-
在此输入
n
,然后回车,表示创建一个新分区(new)。 -
接下来会要求选择分区类型,直接回车即可。(输入p表示主分区,e表示逻辑分区,这里直接回车表示默认值p。)
-
下面将依次要求输入分区号(Partition number ),第一扇区(First sector)和末尾扇区(Last sector),全部都直接回车即可。
-
然后这是重新出现上边的Command行,输入
w
然后回车(write),分区完成。
检查结果
此时再次使用 lsblk
检查一下:
Plain Text
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 30G 自定义头像在/var/lib/AccountsService0 disk
├─sda1 8:1 0 300M 0 part /boot/efi
└─sda2 8:2 0 29.7G 0 part /
sdb 8:16 0 8G 0 disk
└─sdb1 8:17 0 8G 0 part
发现 sdb
出现了一个分区 sdb1
。
格式化
格式化分区是将一个空的分区(不是磁盘)设置文件系统,以便挂载使用(没有经过格式化的分区是无法挂载使用的)。该操作会让分区内的全部文件丢失。
将 sdb1
分区格式化为ext4需要用到的命令是:
Shell Session
sudo mkfs.ext4 /dev/sdb1
稍等片刻,格式化就完成了。
使用命令 lsblk -f
可以检查是否成功, -f
的意思是filesystem(文件系统)。
Plain Text
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
sda
├─sda1 vfat 417A-6A4F /boot/efi
└─sda2 ext4 8b47d5d9-affa-44ae-b645-86c6880a079c 19.7G 27% /
sdb
└─sdb1 ext4 624c46ab-ed5a-4c64-bff9-4b0ae3f90695
可以看到,sdb1的文件系统变更为ext4。
修改卷标
卷标是用户为磁盘起的一个名字,类似于Windows下对某个分区重命名。要修改卷标首先要知道分区的文件系统,不同文件系统下修改卷标的命令不同。
ext2/ext3/ext4:
Shell Session
sudo e2lable /dev/sdb1 卷标名字
xfs:
Shell Session
sudo xfs_admin -L 卷标名字 /dev/sdb1
挂载和使用
要使用一个磁盘分区,往里边读写文件,必须要将其挂载,这个操作可以理解为将一个磁盘分区和一个文件夹路径关联起来。
挂载
将分区 sdb1
挂载到 /myfile
文件夹需要用到的命令:
Shell Session
sudo mount /dev/sdb1 /myfile
此时执行后便可以通过 /myfile
来访问 sdb1
。
但是需要注意的是,在执行上边这个挂载命令之前,被挂载的文件夹也必须存在。因此,在此之前可能需要创建该文件夹。
Shell Session
sudo mkdir /myfile
使用 lsblk
检查结果:
Plain Text
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 30G 0 disk
├─sda1 8:1 0 300M 0 part /boot/efi
└─sda2 8:2 0 29.7G 0 part /
sdb 8:16 0 8G 0 disk
└─sdb1 8:17 0 8G 0 part /myfile
可以看到,sdb1的挂载点已经被设置为/myfile。
此时若无法在其中创建文件,说明没有权限。此时可以使用下面的命令修改所有者。
Shell Session
sudo chown -R test:test /myfile
chown用于修改文件或文件夹的所有者,-R参数表示影响到该文件夹内的所有文件和子文件夹。 test:test
分别表示所有者和组。
使用下面这个命令检查所属是否修改成功:
Shell Session
ls -l / | grep myfile
结果如下:
Plain Text
drwxr-xr-x 2 test test 4096 11月 22 11:24 myfile
若失败,上边那两个test应该全为root。
卸载
卸载使用命令 umount
,也就是取消挂载。可以有两种方式:
-
通过分区名卸载
-
通过挂载点卸载
Shell Session
# 下面这两行命令,任意一行都可以取消上边的挂载。
sudo umount /dev/sdb1
sudo umount /myfile
自动挂载
通常一个常用磁盘,我们不希望每次开机都要重新去执行命令挂载。因此可以设置开机自动挂载。
描述自动挂载的配置文件位于 /etc/fstab
,使用cat命令查看可以看到:
Plain Text
# /dev/sda2
UUID=8b47d5d9-affa-44ae-b645-86c6880a079c / ext4 rw,relatime 0 1
# /dev/sda1
UUID=417A-6A4F /boot/efi vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 2
其中,以#开头的为注释,是解释性的文本。
要设置 sdb1
分区的自动挂载,可以在末尾添加一行:
Plain Text
/dev/sdb1 /myfile ext4 defaults 0 0
保存后退出即可。此时可以重启检查是否按照预期自动挂载了。
在这行的首部,我们直接写了这个分区的设备路径 /dev/sdb1
,但通常不建议这么写。因为这个名称不是固定的,当设备换了个接口,或者加入了其他设备,这个路径可能会变化,例如可能变成 /dev/sdc1
。因此,推荐使用一个固定的标志——UUID来进行挂载。
获取分区的UUID:
使用 lsblk -f
命令:
Plain Text
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
sda
├─sda1 vfat 417A-6A4F /boot/efi
└─sda2 ext4 8b47d5d9-affa-44ae-b645-86c6880a079c 19.7G 27% /
sdb
└─sdb1 ext4 624c46ab-ed5a-4c64-bff9-4b0ae3f90695
得到 sdb1
的UUID为 624c46ab-ed5a-4c64-bff9-4b0ae3f90695
,所以,上边那一行可以替换为:
Plain Text
UUID=624c46ab-ed5a-4c64-bff9-4b0ae3f90695 /myfile ext4 defaults 0 0
这时除非分区被重新格式化,否则这个配置将永远生效。
交换分区和交换文件
交换分区和交换文件差不多,都是把硬盘的一部分空间作为内存的扩展,同时也可以用来支持系统的休眠,因为硬盘断电是不会丢失数据的。
创建交换文件:
Shell Session
sudo dd if=/dev/zero of=/swapfile bs=1G count=1
上边这个命令是使用 zero
设备创建一个空文件 /swapfile
,这个文件的大小由最后两个参数决定,文件大小是两个参数之积。比如这个就是创建了1G的文件。
格式化该文件:
Shell Session
sudo mkswap /swapfile
将该文件格式化为swap,这时才可以使用。但是在这之前需要将其权限更改为 600
。
Shell Session
sudo chmod 600 /swapfile
之后再启用:
Shell Session
sudo swapon /swapfile
使用 swapon -s
可以查看当前正在使用的交换分区或交换文件。
设置交换分区的方式大同小异,但是比交换文件更简单,只需要格式化,然后使用 swapon
命令启用即可。想要每次开机自动挂载,可以修改fstab文件,文件系统设置为swap即可。
磁盘配额管理
可以使用磁盘配额为用户或组限定磁盘的可用空间。这里针对ext4文件系统操作,其他文件系统会有差异。
挂载
想要使用磁盘配额,在挂载时需要添加一些选项:
手动挂载:
Shell Session
sudo mount -o usrquota,grpquota /dev/sdb1 /mnt/disk2/
自动挂载,需要编辑 /etc/fstab
:
Shell Session
/dev/sdb1 /mnt/disk2/ ext4 defaults,usrquota,grpquota 0 0
上面的 usrquota,grpquota
选项可以根据实际情况选择,如果不需要用户组配额,那可以去掉 grpquota
选项。
当挂载成功后,可以使用mount检查是否成功。
Shell Session
mount | grep /dev/sdb其他1
获得如下结果:
Shell Session
/dev/sdb1 on /myfile type ext4 (rw,relatime,quota,usrquota,grpquota)
括号中包括了quota,usrquota,grpquota,说明挂载成功了。
这里如果挂载失败,那后边创建配置文件的时候会出现下面的错误:
Shell Session
quotacheck: Cannot find mountpoint for device /dev/sdb1
quotacheck: No correct mountpoint specified.
quotacheck: Cannot initialize mountpoint scan.
这时先卸载后重新挂载即可。
配置磁盘配额
由于ext4文件系统,quota功能默认是不开启的,需要使用 quotacheck
创建磁盘配额的配置文件:
Shell Session
sudo quotacheck -c /dev/sdb1
或者:
Shell Session
sudo quotacheck -cvug /dev/sdb1
这些选项的含义:
-c:创建配置文件
-v:显示扫描过程
-u:针对扫描用户的情况建立aquota.user
-g:针对扫描组的情况建立aquota.group
配置文件创建完成后就需要开始配置了。以用户test为例:
Shell Session
sudo edquota -u test
这里的 -u
指的指定用户,需要在其后边追加用户名。
此时将使用编辑器打开配置文件,其中每一项的含义:
表头 | 含义 |
---|---|
文件系统(filesystem) | 说明该限制值是针对哪个文件系统(或分区) |
磁盘容量(blocks) | 此列的数值是 quota 自己算出来的,单位为 Kbytes,不要手动修改; |
磁盘容量的软限制(soft) | 当用户使用的磁盘空间超过此限制值,则用户在登陆时会收到警告信息,告知用户磁盘已满,单位为 KB |
磁盘容量的硬限制(hard) | 要求用户使用的磁盘空间最大不能超过此限制值,单位为 KB |
文件数量(inodes) | 同 blocks 一样,此项也是 quota自己计算出来的,无需手动修改 |
文件数量的软限制(soft) | 当用户拥有的文件数量超过此值,系统会发出警告信息; |
文件数量的硬限制(hard) | 用户拥有的文件数量不能超过此值。 |
开启磁盘配额
启用磁盘配额可以使用命令:
Shell Session
sdo quotaon /dev/sdb1
查看当前的打开状态:
Shell Session
sudo quotaon -p /dev/sdb1
用户管理
root用户通常是系统中自带的,具有最高权限的用户,是管理员。一般来说,我们开机进入系统后,登录的用户是普通用户,例如 test
。
新建用户
使用 useradd
命令进行用户的创建。
创建一个普通用户:
Shell Session
sudo useradd test2
创建时设置主组使用 -g
:
Shell Session
sudo useradd -g test2 test2
为添加的用户指定附加wheel用户组可以使用 -G
选项:
Shell Session
sudo useradd -G wheel test2
更多选项可以使用 -h
查看,不一一介绍。
删除用户
使用 userdel
命令进行用户的删除。
删除一个test用户:
Shell Session
sudo userdel test
删除用户的同时,删除用户主目录使用 -r
选项:
Shell Session
sudo userdel -r test
权限和所属
配置文件权限使用 chmod
命令,配置所属用 chown
命令。
权限描述
权限信息可以使用三个数字表示(例如644,755,777等):
计算方法:
这三个数字其实是三组三位二进制数字。其中三组分别表示三个角色:所属用户(u)、所属组(g)、其他(o)。每组中的三位分别是rwx(read、write、executable):
Plain Text
所有者 组内 其他
110 100 100
rw- r-- r–
例如上边就表示自己可读可写,组内的和其他用户只可读,所有人都无权执行。转化成十进制是 644
。
设置权限
将文件abc设置权限的命令就是:
Plain Text
chmod 644 abc
若想针对一个权限修改,比如给组内用户加上可写的权限:
Shell Session
chmod g+w abc
g表示组,省略后则表示所有,也可以写多个。例如:
Plain Text
# 自己,组内,其他用户都赋予可写权限。
chmod +w abc
# 自己,组内赋予可执行权限。
chmod ug+w abc
# 剥夺组内的可执行权限
chmod g-x abc
所属配置
一个文件可以设置其所有者和分组。
将文件abc设置成maicss用户所有,wheel组所有:
Shell Session
chown maicss:wheel abc
sudo和su
简介
sudo的作用是使用某用户的身份去执行一条命令,su的作用是将当前终端切换至某个用户。也就是说,他们并不只有切换到root身份的作用,但如果不指定,默认就会使用root用户。
举个例子:
Shell Session
sudo -u root yum makecache
这里使用了 -u
选项指定了root用户,去运行 yum makecache
这条命令。这句话可以简化为:
Shell Session
sudo yum makecache
因为不指定用户的话,默认就以root身份去运行。这里若需要输入密码,应输入的是当前用户的密码。
su的作用是直接切换至指定用户,若不指定,默认会使用root用户。
举个例子:
Shell Session
su root
这个是切换至root用户。可以简化为:
Shell Session
su
和上边一样,不指定用户名默认为root。但是su命令在输入密码时应当输入目标用户的密码。比如切换至root,就要输入root的密码。但是也可以规避一下:
Shell Session
sudo su
使用sudo命令运行su,因为sudo要求输入当前用户的密码,以root身份运行su可以不用输入目标用户的密码。
配置sudo
可以使用visudo进行编辑,这个命令会调用默认的文本编辑器编辑sudo的配置文件。但是运行这条命令需要root权限。
Shell Session
sudo visudo
配置文件实际的路径是 /etc/sudoers
。可以使用 cat
命令查看,但不建议直接使用文本编辑器编辑。
关于配置的详细说明:https://wiki.archlinux.org/title/Sudo_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#%E9%85%8D%E7%BD%AE
包管理(RPM和YUM)
RPM和YUM的关系
rpm是相对底层的包管理机制,他只提供了基础的包管理功能,而yum是基于rpm,添加了网络功能、自动处理依赖等更实用的高级功能。可以理解为一个是底层(rpm),一个是上层(yum)。yum可以实现rpm的大部分功能。
软件包的依赖
依赖这一机制解决了很多问题,也引发了很多问题。
这里举个例子更容易理解,比如A包是一套餐具,B包是一双筷子,C包是一个盘子。那么很可能A包就要依赖于B包和C包,但是A包还会提供其他的内容,诸如一个碗,一个茶杯,一个保护膜。这种情况下,需要先安装包B和包C,才能安装包A。
rpm的使用
对于rpm的使用,只需要了解最基础的就好,用的不多。
下面是简单的介绍,相对详细的介绍看老师的文档。
rpm.doc0.3MB预览
安装软件
rpm只能安装单个的rpm包,并且不能自动处理依赖。
安装abc.rpm包的命令:
Shell Session
sudo rpm -ivh abc.rpm
这里如果有不满足的依赖问题,那么安装将失败,并提醒用户有那些依赖还未满足。
这里abc.rpm还可以是一个网络链接,比如http或ftp链接。
卸载软件
卸载软件可以用 -e
选项,例如:
Plain Text
sudo rpm -evh <包名>
这里需要注意的是,卸载命令要用到的是包名,而不是包的文件名。包名是固定的,是打包者赋予包的一个属性,无论文件名怎么变,包名是不会变的。包名也是识别不同包的唯一标识。(但文件名通常也是具有一定的命名规范的:软件名-版本号-释出号.体系号.rpm)
可以使用 -qa
命令显示系统中安装的所有包。
Shell Session
sudo rpm -qa
要查询包名中带qq的包:
Shell Session
sudo rpm -qa | grep qq
可以得到:
Plain Text
linuxqq-2.0.0-b2.x86_64
这时候就可以根据得到的包名,卸载该包:
Plain Text
sudo rpm -e linuxqq
yum的使用
这个命令有链接远程仓库的功能,有安装本地包的功能,也可以自动处理依赖,功能十分强大。
配置仓库
他可以实现直接从远程仓库中将软件包下载下来直接安装,所谓远程仓库,就是一个远程服务器,里边存着很多很多的软件,当你指定安装某个软件包时,它会先在远程仓库查找,若找到,则下载并安装,同时下载安装所需要的依赖。
仓库文件位于 /etc/yum.repos.d
中,所有以 .repo
为后缀名的文件,将被识别为仓库。其中一个文件内容:
Plain Text
[microsoft-edge]
name=microsoft-edge
baseurl=https://packages.microsoft.com/yumrepos/edge/
enabled=1
gpgcheck=1
gpgkey=https://packages.microsoft.com/keys/microsoft.asc
上面是edge浏览器配置的仓库源,下面是每一行的解释:
-
仓库名称:这个在更新仓库缓存或者安装软件时会显示,只是一个名字。
-
同上
-
基本URL:就是指定这个仓库的地址,软件会从这里下载。
-
是否激活:可以省略,默认就是1(激活)。
-
gpg检查:这个取决于远程仓库是否支持,若不支持只能为0,支持的话最好为1,(老师上课时提供的源这一项是关闭的,也就是0)
-
gpgkey:只有当5为1的时候,这一项才有意义。
这个文件就是为yum提供了一个远程仓库,这个远程仓库用于安装和更新edge浏览器。
配置远程仓库完成后,往往需要更新缓存:
Shell Session
sudo yum makecache
当远程仓库发生变化时(也包括仓库中软件升级),是必须要更新缓存的,有时这个动作yum会自动进行,但有时手动更新更好。
安装软件
上边提到,yum可以从远程仓库下载安装,也可以从本地直接安装。
远程仓库下载安装的命令:
Shell Session
sudo yum install ftp
上边这条命令就是从远程仓库搜索并下载安装ftp。
若有本地包abc.rpm,安装命令为:
Shell Session
sudo yum localinstall ./abc.rpm
卸载软件
卸载lftp可以用:
Shell Session
sudo yum remove lftp
这里如果lftp有依赖已经不被任何软件需要了,会自动卸载依赖。
更新系统
更新系统的意思就是说,将所有相对远程仓库中较旧的包,更新至与远程仓库中一致。
Shell Session
sudo yum update
进程管理
每执行一个程序都称之为一个进程,同时每一个进程都会分配一个ID号,使用命令 ps
可以查看到当前系统中正在执行的进程的各种进程信息。
查看进程状态
显示当前终端的所有进程信息:
Plain Text
ps -a
显示系统中所有进程:
Plain Text
ps -A
显示后台运行的进程:
Plain Text
ps -x
显示所有运行的程序(包含命令行):
Plain Text
ps -ef
这条命令中 -e
表示显示所有进程, -f
表示全格式。与这条用法功能相似的也可以是下面这样:
Shell Session
ps aux
这是由于语法风格等因素产生了差异,下边会提到。
查找属于用户test的进程信息:
Plain Text
ps -u test
可以使用 grep
对上边所得到的结果进行筛选。比如,要查找进程qq的信息:
Plain Text
ps -ef | grep qq
查询特定的进程还可以用
Plain Text
ps -aux | grep 进程关键字
ps aux 的输出内容有:
表头 | 说明 |
---|---|
USER | 行程所有者 |
PID | 进程号 |
%CPU | 占用的CPU的使用率 |
%MEM | 进程占用物理内存的百分比 |
VSZ | 进程占用的虚拟内存大小 |
RSS | 进程占用的物理内存大小 |
TTY | 终端名称 |
STAT | 进程状态 |
START | 进程的启动时间 |
TIME | CPU时间,即进程使用CPU的总时间 |
COMMAND | 启动进程所用的命令和参数 |
STAT中进程状态有:
-
D:无法中断的休眠状态
-
R:正在执行中
-
S:静止状态
-
T:暂停状态
-
Z:不存在但暂时无法消除
-
W:没有足够的内存可分配
-
<:高优先序的进程
-
N:低优先序的进程
查看命令的时候还可以使用 pstree
命令,该命令会将程序进程以树狀图的形式显示出来
显示所有进程的所有详细信息:
Plain Text
pstree -a
显示当前所有进程的进程号和ID
Plain Text
pstree -p
终止进程
杀死进程的方法一共有三种以下三种:
命令 | 作用 |
---|---|
kill | 在kill后面加上所要杀死的进程号即可,其主要作用是给进程发送信号。 |
killall | 通过进程名称杀死进程 |
kill -9 | 主动杀死程序,一般程序无响应可以用这个。 |
优先级
进程的优先级用 nice
值来表示,在程序中表示为 NI
,nice命令可以用来调整程序运行的优先级。范围从 -20~19
,数值越小,优先级越高。
查看优先级:
Plain Text
top
也可以用ps指令查看目前程序的优先级
Plain Text
ps -le
nice命令可以修改新执行的命令,给其直接赋予NI值,但是却不能给已经存在的进程赋予新的NI值
命令为:
Plain Text
nice -n NI值 要赋予的新命令
例如:
Plain Text
nice -n -5 service httpd start
renice命令是修改已经存在的进程的NI值的命令
命令为:
Plain Text
renice {优先级} 进程号
例如:
Plain Text
renice -10 2105
计划执行任务
周期性执行(crontab)
周期性执行任务需要使用cron管理,对应的命令是 crontab
,对应的服务为 crond
。要使用这个命令,首先需要启动这个服务。
Shell Session
sudo systemctl restart crond
使用 status
选项查看服务的运行状态:
Shell Session
sudo systemctl status crond
服务运行完成后根据需求编辑配置文件:
配置文件示例如下:
Plain Text
0 */2 * * * systemctl restart httpd
10 7 * * * systemctl restart network; date >> /network_log
上边文件中有两行,第一行为每两小时重启一次httpd服务,第二行表示每天的7:10重启网络服务,并且将此刻的时间输出到 /network_log
下。其中,每一行都有两部分,前边部分表示时间,后边部分表示任务。
格式如下:
Plain Text
* * * * * command
- - - - -
| | | | |
| | | | ±---- 星期中星期几 (0 - 6) (星期天 为0)
| | | ±--------- 月份 (1 - 12)
| | ±-------------- 一个月中的第几天 (1 - 31)
| ±------------------- 小时 (0 - 23)
±------------------------ 分钟 (0 - 59)
其中时间表示一些简单的语法,以分钟举例:
-
在其中
*
表示每分钟,*/2
就表示每两分钟。 -
若为纯数字,如
3
就是当分钟数为3的时候,例如12:03
。 -
若有
-
,则表示“至”,如10-30
就是在10分至30分内的每分钟。 -
逗号
,
分格多个条件,比如1,3,5
就是1分、3分、5分时分别执行一次。
下面举一些例子:
每周三和周五的晚上8点整更新系统:
Plain Text
0 20 * * 3,5 yum update
每个月的前十天每天早上6点更新系统并删除 /log
:
Plain Text
0 6 1-10 * * yum update;rm /log
若将配置文件编辑好后,可使用crontab命令启用(若配置文件的名称为a.txt):
Shell Session
crontab a.txt
也可以直接使用 crontab -e
参数直接为当前用户编辑配置文件(若没有会为你自动创建,无需自己创建),所有crontab的参数如下:
选项 | 说明 |
---|---|
-u | 指定某个用户,若省略,默认是当前用户 |
-e | 编辑某个用户的crontab |
-r | 删除某个用户的crontab |
-l | 列出某个用户的crontab |
其中-u选项,书中写的是默认为root用户,但通过查询man手册,其中明确指出该选项若未指定,则默认为执行crontab命令的用户,也就是当前用户。原文如下:
定时执行(at)
定时执行命令需要使用的命令是 at
命令,其依赖于 atd
服务,若提示下面这条信息:
Plain Text
Can’t open /var/run/atd.pid to signal atd. No atd running?
这时就表示 atd
服务没有执行,需要使用命令执行:
Plain Text
sudo systemctl start atd
at的语法为:
Plain Text
at [-f file] [mldv] TIME
at
命令的常用选项:
用法 | 说明 |
---|---|
-d | 删除指定的定时命令 |
-l | 列出所有的定时命令 |
-m | 定时命令执行完成后将输入的结果通过e-mail发送给用户 |
-v | 列出所有已经完成的但并未删除的命令 |
-f file | 读入预先写好的命令文件,用户可以不使用交互模式(不带-f选项)来输入命令,而是将所有的命令先写入文件file后再一次读写 |
交互模式
例如在某年某月某日什么时间执行一次命令(使用交互模式下):
Plain Text
at 08:45 12/1/2021
这条命令表示在2021年12月1日的8点45分,执行该命令后,进入交互模式
Plain Text
at> touch /root/a.txt
在交互模式下,会出现 at>
标志 。在此标志后逐行输入要执行的命令。退出交互模式使用 Ctrl+D
。
非交互模式
不使用交互模式执行命令需要先写好命令在文件夹 file
中:
Plain Text
vim file.txt
在file里填写自动关机的命令:
Plain Text
shutdown now
使用at命令在不进入交互模式下运行命令如下:
Plain Text
at -f file.txt 08:45
删除和查询
命令 | 说明 |
---|---|
atq | 查询当前用户正在等待的计划任务 |
atrm <任务号> | 删除正在等待的计划任务 |
系统服务
目前主流的发行版中,一般使用 systemd
对系统进行初始化,对其进行控制的命令是 systemctl
。systemd应当是是系统中的第一个进程。
服务的启动和停止
举例:
启动http服务:
Shell Session
sudo systemctl start httpd
停止http服务:
Shell Session
sudo systemctl stop httpd
重启http服务:
Shell Session
sudo systemctl restart httpd
查看http服务的状态:
Shell Session
sudo systemctl status httpd
设置开机启动
举例:
设置网络服务开机自动启动:
Shell Session
sudo systemctl enable network
关闭网络服务开机自动启动:
Shell Session
sudo systemctl disable network
列出系统中可用服务
Shell Session
systemctl # 列出所有的系统服务
systemctl list-units # 列出所有启动unit
systemctl list-unit-files # 列出所有启动文件
systemctl list-units –type=service –all # 列出所有service类型的unit
systemctl list-units –type=service –all | grep cpu # 列出 cpu电源管理机制的服务
systemctl list-units –type=target –all # 列出所有target
电源管理
Shell Session
systemctl poweroff # 系统关机
systemctl reboot # 重新启动
systemctl suspend # 进入睡眠模式
systemctl hibernate # 进入休眠模式
systemctl rescue # 强制进入救援模式
systemctl emergency # 强制进入紧急救援模式
修改系统目标(target)
运行级别 | target | 说明 |
---|---|---|
0 | poweroff.target | 中断,停机状态(不能设置为默认级别,否则无法正常开机) |
1 | rescue.target | 单用户状态,root权限 |
2 | multi-user.target | 多用户,不支持NFS |
3 | multi-user.target | 完全多用户(支持NFS),命令行模式 |
4 | multi-user.target | 未使用,保留 |
5 | graphical.target | 图形模式 |
6 | reboot.target | 正常关闭并重启(不能设置为默认级别,否则无法正常开机) |
切换运行级别:
Shell Session
systemctl isolate multi-user.target
设置默认级别:
Shell Session
sudo systemctl enable multi-user.target
sudo systemctl set-default multi-user.target
搭建FTP服务器
部署
要搭建ftp服务器,需要先安装vsftpd软件包:
Shell Session
sudo yum install vsftpd
安装后系统中会出现一个名为vsftpd的服务。
配置
vsftpd的配置文件位于 /etc/vsftpd/vsftpd.conf
,下面是一部分选项的说明:
Shell Session
anonymous_enable=YES #允许匿名用户访问
anon_upload_enable=YES #允许匿名用户上传
anon_mkdir_write_enable=YES #允许匿名用户创建文件夹
anon_root=/ftp #匿名用户默认的ftp目录,默认是/var/ftp
local_enable=YES #保证本地账户可以登录
local_root=/ftp1 #修改本地账户的默认ftp目录,否则会出现在家目录中
更多配置信息我在博客中整理了一部分:https://maicss.gitee.io/2021/09/03/ftp-server-config/
vsftpd默认路径位于:/var/ftp/
为了防止访问时遇到权限不足的问题,可更改自定义的ftp文件夹权限:
Shell Session
sudo chmod 777 -R /var/ftp/pub
启动和关闭服务
ftp服务可以使用 systemd
进行管理。
开启服务:
Shell Session
sudo systemctl start vsftpd
关闭服务:
Shell Session
sudo systemctl stop vsftpd
防火墙和selinux
如果想要令其他电脑访问,可以关闭防火墙和selinux:
Shell Session
sudo systemctl stop firewalld
sudo setenforce 0
不过更推荐使用下面这个命令为防火墙添加ftp服务,这样就不必关闭防火墙了:
Shell Session
sudo firewall-cmd --permanent --zone=public --add-service=ftp
sudo firewall-cmd --reload
关闭SElinux
临时关闭:
Shell Session
sudo setenforce 0
永久关闭:
修改/etc/selinux/config
将 SELINUX=enforcing
更改为 permissive
即可,当打开该配置文件中,其中有详细说明注释,selinux有三个选项:
-
enforcins: 强制执行 SELinux 安全策略。
-
permissive: SELinux 打印警告而不是强制执行。
-
disabled: 不加载 SELinux 策略。
当使用 setenforce
设置时,1表示enforcins,0表示permissive,也可以直接写对应单词。
搭建samba共享
部署
首先需要安装 samba
包。
Shell Session
sudo yum install samba
这会产生一个名为smb的系统服务。
配置
创建共享文件夹
Shell Session
sudo mkdir /share
sudo chmod 777 -R /share
修改配置文件/etc/samba/smb.conf,在[globla]段添加:
Shell Session
map to guest = Bad User
这个配置的作用是实现匿名登录时无须交互输入用户名和密码。
在文件中添加自定义共享文件夹段落:
Plain Text
[myshare]
path=/share
public=yes
browseable=yes
writable=yes
开启服务:
Shell Session
sudo systemctl start smb
允许以本地用户的身份登录,需要添加已有用户到smb服务用户列表,并设置smb访问密码:
Shell Session
sudo smbpasswd -a test
然后在配置文件中注释或删除掉 map to guest = Bad User
最后重启smb服务:
Shell Session
sudo systemctl restart smb
搭建http服务器
要使用简单的http服务,需要安装 httpd
包:
Shell Session
sudo yum install httpd
其默认路径位于 /var/www/http
,将网页文件放置在这里,命名为index.html,即可通过http服务访问。不过在此之前需要启动服务:
Shell Session
sudo systemctl start httpd
Shell(bash)脚本编写
如果有了解过python的可能比较容易理解,脚本就是一个文本文件,需要使用解释器来运行他,不需要进行编译。但他和编程语言一样,也有标准的语法、结构,可以当成一个语言去学习。
入门
要编写shell脚本,需要了解一个概念,就是解释器,它是负责解读和运行这个脚本的程序。所编写的脚本都要符合他的语法。常见的脚本解释器有python,php,bash等。bash是大多数Linux发行版的默认shell,因此,这里我们学习的脚本也就是bash脚本。
编写一个简单的脚本:
最简单的脚本可以只有一个命令,比如新建一个文件名为 hello.sh
,在里边写入:
Shell Session
echo hello world!
上边这个命令我们可以直接在终端中运行,因为终端中的shell就是bash。当我们将其写入一个文件后,这个文件就是脚本。
下面需要为这个脚本赋予可执行权限:
Shell Session
chmod +x hello.sh
然后运行:
Shell Session
./hello.sh
这时候就会在下面输出 hello world!
的字样了。
在上边这个过程中,有两个问题需要说明一下:
-
hello.sh的后缀名有什么讲究?
-
运行的时候为什么要在前边加一个
./
?
之所以将其后缀名命名为.sh是出于习惯问题,通常.sh表示该文件是一个脚本文件,但这没有任何实际的影响,你甚至都可以不加后缀名。
运行时在文件名前加一个 ./
的原因是当你运行程序时,必须输入一个路径,这个路径可以是相对路径或者绝对路径,如果输入的不是一个路径,那么它就会去PATH环境变量包含的路径下去寻找,结果找不到就无法运行。
解释器
因为不同的解释器有不同的语法,因此我们需要在运行时告知系统该脚本要使用何种解释器。
通常,我们会在文件的首行位置声明解释器:
Shell Session
#!/bin/bash
echo “Hello World!”
这时候就可以使用 ./hello.sh
来运行脚本了。其中 #!
表示声明这个脚本要使用的解释器程序,一般写绝对路径,若不清楚解释器在哪,可以使用 whereis
命令。
也可以将脚本作为解释器的参数运行,这时候使用 #!
声明的解释器就没有效果了。
例如:
Shell Session
bash hello.sh
这时候就相当于使用bash直接运行这个脚本,这种情况下无论首行声明了什么解释器,都会使用bash解释器运行。
所以,要运行脚本文件,有三种方式:
在脚本首行声明解释器。
Shell Session
#!/bin/bash
echo “Hello World!”
-
在声明解释器后,直接输入相对路径
./hello.sh
即可运行。 -
在声明解释器后,使用绝对路径
/home/test/hello.sh
运行。 -
使用解释器程序直接运行。
Shell Session
bash hello.sh
语法
脚本的语法也是非常丰富的,并非一两句就能说明白。这里就简单介绍一下变量和参数,若想了解更多可以去寻找相关资料,这里推荐几个:
-
菜鸟教程:https://www.runoob.com/linux/linux-shell.html
-
W3Cschool:https://www.w3cschool.cn/linux/linux-shell.html
-
GNU官方文档(英文):https://www.gnu.org/software/bash/manual/bash.html
变量
要想在脚本中创建一个变量,可以直接为一个不存在的变量名赋值:
Shell Session
#!/bin/bash
MY_NAME=Maicss
echo “My Name is ${MY_NAME}”
注意等号两边不能有空格。
若想修改这个变量的值,和创建时一样:
Shell Session
#!/bin/bash
MY_NAME=Maicss
echo “My Name is ${MY_NAME}”
MY_NAME=Liu
echo “My Name is ${MY_NAME}”
变量类型
运行shell时,会同时存在三种变量:
-
局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
-
环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
-
shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
参数
参数就是当运行一个程序是,在后边传入的参数,例如我们以前接触到的命令中 cat a.txt
其中的 a.txt
就是cat的参数,参数也可以有多个,例如 cp a.txt b.txt
,这就为cp命令传递了两个参数。
要想让自己写的脚本也拥有参数,也可以使用 $
符号。
例如写以下脚本:
Shell Session
#!/bin/bash
echo “Hello $1”
若文件名为 hello.sh
此时可以运行 ./hello.sh Maicss
,这时就会出现 Hello Maicss
的字样。
其中 $1
中的数字1就代表第一
名称 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。意思就是把所有的参数练成一个字符串的结果。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |