常用操作以及概念
快捷键
- Tab:命令和文件名补全;
- Ctrl+C:中断正在运行的程序;
- Ctrl+D:结束键盘输入(End Of File,EOF)
求助
--help
指令的基本用法与选项介绍。
man
man 是 manual 的缩写,将指令的具体信息显示出来。当执行 man date
时,有 DATE(1) 出现,其中的数字代表指令的类型,常用的数字及其类型如下:
代号 | 类型 |
---|---|
1 | 用户在 shell 环境中可以操作的指令或者可执行文件 |
5 | 配置文件 |
8 | 系统管理员可以使用的管理指令 |
Linux配置中文版man手册。
# 1. 下载源码包
$ wget https://src.fedoraproject.org/repo/pkgs/man-pages-zh-CN/manpages-zh-1.5.1.tar.gz/13275fd039de8788b15151c896150bc4/manpages-zh-1.5.1.tar.gz
# 2. 解压并安装
$ tar -zxvf manpages-zh-1.5.1.tar.gz
$ ./configure --disable-zhtw --prefix=/usr/local/zhman
$ make && make install
# 3. 新建cman命令作为中文查询
$ cd ~
$ echo "alias cman='man -M /usr/local/zhman/share/man/zh_CN' " >> .bash_profile
info
info 与 man 类似,但是 info 将文档分成一个个页面,每个页面可以跳转。
doc
/usr/share/doc 存放着软件的一整套说明文件。
关机
who
在关机前需要先使用 who 命令查看有没有其它用户在线。
sync
为了加快对磁盘文件的读写速度,位于内存中的文件数据不会立即同步到磁盘,因此关机之前需要先进行 sync 同步操作。
shutdown
$ shutdown [-krhc] 时间 [信息]
-k : 不会关机,只是发送警告信息,通知所有在线的用户
-r : 将系统的服务停掉后就重新启动
-h : 将系统的服务停掉后就立即关机
-c : 取消已经在进行的 shutdown
包管理工具
RPM 和 DPKG 为最常见的两类软件包管理工具:
- RPM 全称为 Redhat Package Manager,最早由 Red Hat 公司制定实施,随后被 GNU 开源操作系统接受并成为许多 Linux 系统的既定软件标准。YUM 基于 RPM,具有依赖管理和软件升级功能。
- 与 RPM 竞争的是基于 Debian 操作系统的 DEB 软件包管理工具 DPKG,全称为 Debian Package,功能方面与 RPM 相似。
发行版
Linux 发行版是 Linux 内核及各种应用软件的集成版本。
基于的包管理工具 | 商业发行版 | 社区发行版 |
---|---|---|
RPM | Red Hat | Fedora / CentOS |
DPKG | Ubuntu | Debian |
VIM 三个模式
- 一般指令模式(Command mode):VIM 的默认模式,可以用于移动游标查看内容;
- 编辑模式(Insert mode):按下 "i" 等按键之后进入,可以对文本进行编辑;
- 指令列模式(Bottom-line mode):按下 ":" 按键之后进入,用于保存退出等操作。
磁盘
磁盘的文件名
Linux 中每个硬件都被当做一个文件,包括磁盘。磁盘以磁盘接口类型进行命名,常见磁盘的文件名如下:
- IDE 磁盘:/dev/hd[a-d]
- SATA/SCSI/SAS 磁盘:/dev/sd[a-p]
查看磁盘空间
查看磁盘空间利用大小:
df -h
-h
: human缩写,以易读的方式显示结果(即带单位:比如M/G,如果不加这个参数,显示的数字以B为单位)
df -h
# 文件系统 容量 已用 可用 已用% 挂载点
# devtmpfs 1.9G 0 1.9G 0% /dev
# tmpfs 1.9G 0 1.9G 0% /dev/shm
# tmpfs 1.9G 292K 1.9G 1% /run
# tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
# /dev/vda1 40G 8.0G 30G 22% /
查看当前目录所占空间大小:
du -sh
- -h 人性化显示
- -s 递归整个目录的大小
$ du -sh
# 429M .
分区
分区表
磁盘分区表主要有两种格式。
- MBR 分区表(限制较多)
- GPT 分区表(较新且限制较少)
MBR
MBR 中,第一个扇区最重要,里面有主要开机记录(Master boot record, MBR)及分区表(partition table),其中主要开机记录占 446 bytes,分区表占 64 bytes。
Linux 也把分区当成文件,分区文件的命名方式为:磁盘文件名 + 编号,例如 /dev/sda1。注意,逻辑分区的编号从 5 开始。
GPT
扇区是磁盘的最小存储单位,旧磁盘的扇区大小通常为 512 bytes,而最新的磁盘支持 4 k。
开机检测程序
BIOS
BIOS(Basic Input/Output System,基本输入输出系统),它是一个固件(嵌入在硬件中的软件),BIOS 程序存放在断电后内容不会丢失的只读内存中。不可以读取 GPT 分区表。
安装多重引导,最好先安装 Windows 再安装 Linux。因为安装 Windows 时会覆盖掉主要开机记录(MBR),而 Linux 可以选择将开机管理程序安装在主要开机记录(MBR)或者其它分区的启动扇区,并且可以设置开机管理程序的选单。
UEFI
BIOS 不可以读取 GPT 分区表,而 UEFI 可以。
文件系统
组成
最主要的几个组成部分如下:
- inode:一个文件占用一个 inode,记录文件的属性,同时记录此文件的内容所在的 block 编号;
- block:记录文件的内容,文件太大时,会占用多个 block。
除此之外还包括:
- superblock:记录文件系统的整体信息,包括 inode 和 block 的总量、使用量、剩余量,以及文件系统的格式与相关信息等;
- block bitmap:记录 block 是否被使用的位图。
目录配置
为了使不同 Linux 发行版本的目录结构保持一致性,Filesystem Hierarchy Standard (FHS) 规定了 Linux 的目录结构。最基础的三个目录如下:
/
(root, 根目录)/usr
(unix software resource):所有系统默认软件都会安装到这个目录;/var
(variable):存放系统或程序运行过程中的数据文件。
文件与目录的基本操作
ls
列出文件或者目录的信息,目录的信息就是其中包含的文件。
$ ls [-aAdfFhilnrRSt] file|dir
-a :列出全部的文件
-d :仅列出目录本身
-l :以长数据串行列出,包含文件的属性与权限等等数据
cd
更换当前目录。
$ cd [相对路径或绝对路径]
mkdir
创建目录。
$ mkdir [-mp] 目录名称
-m :配置目录权限
-p :递归创建目录
rmdir
删除目录,目录必须为空。
$ rmdir [-p] 目录名称
-p :递归删除目录
touch
更新文件时间或者建立新文件。
$ touch [-acdmt] filename
-a : 更新 atime
-c : 更新 ctime,若该文件不存在则不建立新文件
-m : 更新 mtime
-d : 后面可以接更新日期而不使用当前日期,也可以使用 --date="日期或时间"
-t : 后面可以接更新时间而不使用当前时间,格式为[YYYYMMDDhhmm]
cp
复制文件。如果源文件有两个以上,则目的文件一定要是目录才行。
$ cp [-adfilprsu] source destination
-a :相当于 -dr --preserve=all
-d :若来源文件为链接文件,则复制链接文件属性而非文件本身
-i :若目标文件已经存在时,在覆盖前会先询问
-p :连同文件的属性一起复制过去
-r :递归复制
-u :destination 比 source 旧才更新 destination,或 destination 不存在的情况下才复制
--preserve=all :除了 -p 的权限相关参数外,还加入 SELinux 的属性, links, xattr 等也复制了
rm
删除文件。
$ rm [-fir] 文件或目录
-r :递归删除
mv
移动文件。
$ mv [-fiu] source destination
$ mv [options] source1 source2 source3 .... directory
-f : force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖
修改权限
可以将一组权限用数字来表示,此时一组权限的 3 个位当做二进制数字的位,从左到右每个位的权值为 4、2、1,即每个权限对应的数字权值为 r : 4、w : 2、x : 1。
更改读写权限
$ chmod [-R] xyz dirname/filename
示例:将 .bashrc 文件的权限修改为 -rwxr-xr--。
$ chmod 754 .bashrc
也可以使用符号来设定权限。
$ chmod [ugoa] [+-=] [rwx] dirname/filename
- u:拥有者
- g:所属群组
- o:其他人
- a:所有人
- +:添加权限
- -:移除权限
- =:设定权限
示例:为 .bashrc 文件的所有用户添加写权限。
$ chmod a+w .bashrc
更改文件或目录的拥有者
$ chown username dirOrFile
使用-R选项递归更改该目下所有文件的拥有者:
$ chown -R weber server/
默认权限
- 文件默认权限:文件默认没有可执行权限,因此为
666
,也就是-rw-rw-rw-
。 - 目录默认权限:目录必须要能够进入,也就是必须拥有可执行权限,因此为
777
,也就是drwxrwxrwx
。
链接
$ ln [-sf] source_filename dist_filename
-s :默认是实体链接,加 -s 为符号链接
-f :如果目标文件存在时,先删除目标文件
实体链接
在目录下创建一个条目,记录着文件名与 inode 编号,这个 inode 就是源文件的 inode。
删除任意一个条目,文件还是存在,只要引用数量不为 0。
有以下限制:不能跨越文件系统、不能对目录进行链接。
$ ln /etc/crontab .
$ ll -i /etc/crontab crontab
# 34474855 -rw-r--r--. 2 root root 451 Jun 10 2014 crontab
# 34474855 -rw-r--r--. 2 root root 451 Jun 10 2014 /etc/crontab
符号链接
符号链接文件保存着源文件所在的绝对路径,在读取时会定位到源文件上,可以理解为 Windows 的快捷方式。
当源文件被删除了,链接文件就打不开了。
因为记录的是路径,所以可以为目录建立符号链接。
$ ll -i /etc/crontab /root/crontab2
# 34474855 -rw-r--r--. 2 root root 451 Jun 10 2014 /etc/crontab
# 53745909 lrwxrwxrwx. 1 root root 12 Jun 23 22:31 /root/crontab2 -> /etc/crontab
获取文件内容
cat
取得文件内容。
$ cat [-AbEnTv] filename
-n :打印出行号,连同空白行也会有行号,-b 不会
tac
是 cat 的反向操作,从最后一行开始打印。
more
和 cat 不同的是它可以一页一页查看文件内容,比较适合大文件的查看。
less
和 more 类似,但是多了一个向前翻页的功能。
head
取得文件前几行。
$ head [-n number] filename
-n :后面接数字,代表显示几行的意思
tail
是 head 的反向操作,只是取得是后几行。
od
以字符或者十六进制的形式显示二进制文件。
指令与文件搜索
which
指令搜索。which指令会在环境变量$PATH设置的目录里查找符合条件的文件。
$ which [-a] command
-a :将所有指令列出,而不是只列第一个
whereis
文件搜索。whereis命令首先会去掉filename中的前缀空格和以.开头的任何字符,然后再在数据库(var/lib/slocate/slocate.db)
中查找与上述处理后的filename相匹配的二进制文件、源文件和帮助手册文件。
# updatedb 使用之前可以手动更新数据库
$ whereis [-bmsu] dirname/filename
locate
文件搜索。可以用关键字或者正则表达式进行搜索(只记得某个文件的部分名称)。
locate 使用 /var/lib/mlocate/ 这个数据库来进行搜索,它存储在内存中,并且每天更新一次,所以无法用 locate 搜索新建的文件。
# updatedb 使用之前可以手动更新数据库
$ locate [-ir] keyword
-r:正则表达式
find
文件搜索。可以使用文件的属性和权限进行搜索。
遍历当前工作目录及其子目录,find
命令是在硬盘上遍历查找,非常耗硬盘资源,查找效率相比whereis
和locate
较低。
$ find [basedir] [option]
# example: find . -name "shadow*"
① 与时间有关的选项
-mtime n :列出在 n 天前的那一天修改过内容的文件
-mtime +n :列出在 n 天之前 (不含 n 天本身) 修改过内容的文件
-mtime -n :列出在 n 天之内 (含 n 天本身) 修改过内容的文件
-newer file : 列出比 file 更新的文件
+4、4 和 -4 的指示的时间范围如下:
② 与文件拥有者和所属群组有关的选项
-uid n
-gid n
-user name
-group name
-nouser :搜索拥有者不存在 /etc/passwd 的文件
-nogroup:搜索所属群组不存在于 /etc/group 的文件
③ 与文件权限和名称有关的选项
-name filename
-size [+-]SIZE:搜寻比 SIZE 还要大 (+) 或小 (-) 的文件。这个 SIZE 的规格有:c: 代表 byte,k: 代表 1024bytes。所以,要找比 50KB 还要大的文件,就是 -size +50k
-type TYPE
-perm mode :搜索权限等于 mode 的文件
-perm -mode :搜索权限包含 mode 的文件
-perm /mode :搜索权限包含任一 mode 的文件
压缩与打包
压缩文件名
Linux 底下有很多压缩文件名,常见的如下:
扩展名 | 压缩程序 |
---|---|
*.Z | compress |
*.zip | zip |
*.gz | gzip |
*.bz2 | bzip2 |
*.xz | xz |
*.tar | tar 程序打包的数据,没有经过压缩 |
*.tar.gz | tar 程序打包的文件,经过 gzip 的压缩 |
*.tar.bz2 | tar 程序打包的文件,经过 bzip2 的压缩 |
*.tar.xz | tar 程序打包的文件,经过 xz 的压缩 |
压缩指令
gzip
gzip 是 Linux 使用最广的压缩指令,可以解开 compress、zip 与 gzip 所压缩的文件。
经过 gzip 压缩过,源文件就不存在了。
有 9 个不同的压缩等级可以使用。
可以使用 zcat、zmore、zless 来读取压缩文件的内容。
$ gzip [-cdtv#] filename
-c :将压缩的数据输出到屏幕上
-d :解压缩
-t :检验压缩文件是否出错
-v :显示压缩比等信息
-# : # 为数字的意思,代表压缩等级,数字越大压缩比越高,默认为 6
bzip2
提供比 gzip 更高的压缩比。
查看命令:bzcat、bzmore、bzless、bzgrep。
$ bzip2 [-cdkzv#] filename
-k :保留源文件
xz
提供比 bzip2 更佳的压缩比。
可以看到,gzip、bzip2、xz 的压缩比不断优化。不过要注意的是,压缩比越高,压缩的时间也越长。
查看命令:xzcat、xzmore、xzless、xzgrep。
$ xz [-dtlkc#] filename
打包
压缩指令只能对一个文件进行压缩,而打包能够将多个文件打包成一个大文件。tar 不仅可以用于打包,也可以使用 gzip、bzip2、xz 将打包文件进行压缩。
$ tar [-z|-j|-J] [cv] [-f 新建的 tar 文件] filename... ==打包压缩
$ tar [-z|-j|-J] [tv] [-f 已有的 tar 文件] ==查看
$ tar [-z|-j|-J] [xv] [-f 已有的 tar 文件] [-C 目录] ==解压缩
-z :使用 zip;
-j :使用 bzip2;
-J :使用 xz;
-c :新建打包文件;
-t :查看打包文件里面有哪些文件;
-x :解打包或解压缩的功能;
-v :在压缩/解压缩的过程中,显示正在处理的文件名;
-f : filename:要处理的文件;
-C 目录 : 在特定目录解压缩。
使用方式 | 命令 |
---|---|
打包压缩 | tar -jcv -f filename.tar.bz2 要被压缩的文件或目录名称 |
查 看 | tar -jtv -f filename.tar.bz2 |
解压缩 | tar -jxv -f filename.tar.bz2 -C 要解压缩的目录 |
Bash
可以通过 Shell 请求内核提供服务,Bash 正是 Shell 的一种。
特性
- 命令历史:记录使用过的命令
- 命令与文件补全:快捷键:tab
- 命名别名:例如
ll
是ls -al
的别名 - shell scripts
- 通配符:例如
ls -l /usr/bin/X\*
列出/usr/bin
下面所有以 X 开头的文件
变量操作
对一个变量赋值直接使用 =
。
对变量取用需要在变量前加上 $ ,也可以用 ${} 的形式;
输出变量使用 echo 命令。
$ x=abc
$ echo $x
$ echo ${x}
变量内容如果有空格,必须使用双引号或者单引号。
- 双引号内的特殊字符可以保留原本特性,例如 x="lang is $LANG",则 x 的值为 lang is zh_TW.UTF-8;
- 单引号内的特殊字符就是特殊字符本身,例如 x='lang is $LANG',则 x 的值为 lang is $LANG。
可以使用 `指令` 或者 $(指令) 的方式将指令的执行结果赋值给变量。例如 version=$(uname -r),则 version 的值为 4.15.0-22-generic。
可以使用 export 命令将自定义变量转成环境变量,环境变量可以在子程序中使用,所谓子程序就是由当前 Bash 而产生的子 Bash。
Bash 的变量可以声明为数组和整数数字。注意数字类型没有浮点数。如果不进行声明,默认是字符串类型。变量的声明使用 declare 命令:
$ declare [-aixr] variable
-a : 定义为数组类型
-i : 定义为整数类型
-x : 定义为环境变量
-r : 定义为 readonly 类型
使用 [ ] 来对数组进行索引操作:
$ array[1]=a
$ array[2]=b
$ echo ${array[1]}
指令搜索顺序
- 以绝对或相对路径来执行指令,例如 /bin/ls 或者 ./ls ;
- 由别名找到该指令来执行;
- 由 Bash 内置的指令来执行;
- 按 $PATH 变量指定的搜索路径的顺序找到第一个指令来执行。
数据流重定向
重定向指的是使用文件代替标准输入、标准输出和标准错误输出。
1 | 代码 | 运算符 |
---|---|---|
标准输入 (stdin) | 0 | < 或 << |
标准输出 (stdout) | 1 | > 或 >> |
标准错误输出 (stderr) | 2 | 2> 或 2>> |
<
和 >
表示以覆盖的方式重定向。>>
和 <<
的表示以追加的方式重定向。
/dev/null
,相当于扔进垃圾箱。
如果需要将标准输出以及标准错误输出同时重定向到一个文件,需要将某个输出转换为另一个输出,例如 2>&1
表示将标准错误输出转换为标准输出。
# 找到 /home 目录下的名字为".bashrc"的文件路径,(标准输入和错误输出)写入、覆盖到到list文件中
$ find /home -name .bashrc > list 2>&1
# 找到 /home 目录下的名字带有".bash"的文件路径,(标准输入和错误输出)追加到到list文件中
$ find /home -name ".bash*" >> list 2>&1
管道指令
将一个命令的标准输出作为另一个命令的标准输入。
$ ls -al /etc | less
提取指令
cut
对数据进行切分,取出想要的部分。
切分过程一行一行地进行。
$ cut
-d :分隔符
-f :经过 -d 分隔后,使用 -f n 取出第 n 个区间
-c :以字符为单位取出区间
示例 1:last
显示登入者的信息,取出用户名。
$ last
# root pts/1 192.168.201.101 Sat Feb 7 12:35 still logged in
# root pts/1 192.168.201.101 Fri Feb 6 12:13 - 18:46 (06:33)
# root pts/1 192.168.201.254 Thu Feb 5 22:37 - 23:53 (01:16)
$ last | cut -d ' ' -f 1
示例 2:将 export
输出的信息,取出第 12 字符以后的所有字符串。
$ export
# declare -x HISTCONTROL="ignoredups"
# declare -x HISTSIZE="1000"
# declare -x HOME="/home/dmtsai"
# declare -x HOSTNAME="study.centos.vbird"
# .....(其他省略).....
$ export | cut -c 12-
排序指令
sort
用于排序。
$ sort [-fbMnrtuk] [file or stdin]
-f :忽略大小写
-b :忽略最前面的空格
-M :以月份的名字来排序,例如 JAN,DEC
-n :使用数字
-r :反向排序
-u :相当于 unique,重复的内容只出现一次
-t :分隔符,默认为 tab
-k :指定排序的区间
示例:/etc/passwd
文件内容以 : 来分隔,要求以第三列进行排序。
$ cat /etc/passwd | sort -t ':' -k 3
# root:x:0:0:root:/root:/bin/bash
# dmtsai:x:1000:1000:dmtsai:/home/dmtsai:/bin/bash
# alex:x:1001:1002::/home/alex:/bin/bash
# arod:x:1002:1003::/home/arod:/bin/bash
uniq
可以将重复的数据只取一个。
$ uniq [-ic]
-i :忽略大小写
-c :进行计数
示例:取得每个人的登录总次数
$ last | cut -d ' ' -f 1 | sort | uniq -c
# 1
# 6 (unknown
# 47 dmtsai
# 4 reboot
# 7 root
# 1 wtmp
双向输出重定向
输出重定向会将输出内容重定向到文件中,而tee
不仅能够完成这个功能,还能保留屏幕上的输出。也就是说,使用 tee 指令,一个输出会同时传送到文件和屏幕上。
$ tee [-a] file
字符转换指令
tr
用来删除一行中的字符,或者对字符进行替换。
$ tr [-ds] SET1 ...
-d : 删除行中 SET1 这个字符串
示例,将 last
输出的信息所有小写转换为大写。
$ last | tr '[a-z]' '[A-Z]'
col
将 tab 字符转为空格字符。
$ col [-xb]
-x : 将 tab 键转换成对等的空格键
expand
将 tab 转换一定数量的空格,默认是 8 个。
$ expand [-t] file
-t :tab 转为空格的数量
join
将有相同数据的那一行合并在一起。
$ join [-ti12] file1 file2
-t :分隔符,默认为空格
-i :忽略大小写的差异
-1 :第一个文件所用的比较字段
-2 :第二个文件所用的比较字段
paste
直接将两行粘贴在一起。
$ paste [-d] file1 file2
-d :分隔符,默认为 tab
分区指令
split
将一个文件划分成多个文件。
$ split [-bl] file PREFIX
-b :以大小来进行分区,可加单位,例如 b, k, m 等
-l :以行数来进行分区。
- PREFIX :分区文件的前导名称
正则表达式
grep
g/re/p(globally search a regular expression and print),使用正则表示式进行全局查找并打印。
$ grep [-acinv] [--color=auto] 搜寻字符串 filename
-c : 统计匹配到行的个数
-i : 忽略大小写
-n : 输出行号
-v : 反向选择,也就是显示出没有 搜寻字符串 内容的那一行
--color=auto :找到的关键字加颜色显示
示例:把含有 the 字符串的行提取出来(注意默认会有 --color=auto 选项,因此以下内容在 Linux 中有颜色显示 the 字符串)
$ grep -n 'the' regular_express.txt
8:I can't finish the test.
12:the symbol '*' is represented as start.
15:You are the best is mean you are the no. 1.
16:The world Happy is the same with "glad".
18:google is the best tools for search keyword
示例:正则表达式 a{m,n} 用来匹配字符 a m~n 次,这里需要将 { 和 } 进行转义,因为它们在 shell 是有特殊意义的。
$ grep -n 'a\{2,5\}' regular_express.txt
printf
用于格式化输出。它不属于管道命令,在给 printf 传数据时需要使用 $( ) 形式。
$ printf '%10s %5i %5i %5i %8.2f \n' $(cat printf.txt)
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
awk
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具,由 Alfred Aho,Peter Weinberger 和 Brian Kernighan 创造,awk 这个名字就是这三个创始人名字的首字母。
进程管理
查看进程
ps
查看某个时间点的进程信息。
示例:查看自己的进程
$ ps -l
示例:查看系统所有进程
$ ps aux
示例:查看特定的进程([管道](# 八、管道指令)、正则)
$ ps aux | grep threadx
查询正在运行的进程信息
$ ps -ef
eg:查询归属于用户colin115的进程
$ ps -ef | grep colin115
$ ps -lu colin115
pstree
查看进程树。
示例:查看所有进程树
$ pstree -A
top
实时显示进程信息。
示例:两秒钟刷新一次
$ top -d 2
netstat
查看占用端口的进程
示例:查看特定端口的进程
$ netstat -anp | grep port
lsof
查看端口占用的进程状态:
$ lsof -i:3306
查看用户username的进程所打开的文件
$ lsof -u username
查询init进程当前打开的文件
$ lsof -c init
查询指定的进程ID(23295)打开的文件:
$ lsof -p 23295
pgrep
查询进程ID(适合只记得部分进程字段)
$ pgrep 查找进程
# eg:查询进程名中含有re的进程
$ pgrep -l re
# 2 kthreadd
# 28 ecryptfs-kthrea
# 29515 redis-server
终止进程
杀死指定PID的进程 (PID为Process ID)
$ kill PID
杀死相关进程
$ kill -9 3434
杀死job工作 (job为job number)
$ kill %job
综合运用
将用户colin115下的所有进程名以av_开头的进程终止:
$ ps -u colin115 | awk '/av_/ {print "kill -9 " $1}' | sh
将用户colin115下所有进程名中包含HOST的进程终止:
$ ps -fe| grep colin115|grep HOST |awk '{print $2}' | xargs kill -9;
进程状态
进程状态反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。在三态模型中,进程状态分为三个基本状态,即运行态,就绪态,阻塞态。
状态 | 说明 |
---|---|
R | running or runnable (on run queue) 正在执行或者可执行,此时进程位于执行队列中。 |
D | uninterruptible sleep (usually I/O) 不可中断的睡眠状态, 可处理signal, 有延迟。不可中断阻塞,通常为 IO 阻塞。 |
S | interruptible sleep (waiting for an event to complete) 可中断阻塞,此时进程正在等待某个事件完成。 |
Z | zombie (terminated but not reaped by its parent) 僵死,进程已经终止但是尚未被其父进程获取信息。 |
T | stopped (either by a job control signal or because it is being traced) 结束,进程既可以被作业控制信号结束,也可能是正在被追踪。 |
**R(TASK_RUNNING) 可执行状态 **
只有在该状态的进程才可能在CPU上运行。而同一时刻可能有多个进程处于可执行状态,这些进程的task_struct结构(进程控制块)被放入对应CPU的可执行队列中(一个进程最多只能出现在一个CPU的可执行队列中)。进程调度器的任务就是从各个CPU的可执行队列中分别选择一个进程在该CPU上运行。
很多操作系统教科书将正在CPU上执行的进程定义为RUNNING状态、而将可执行但是尚未被调度执行的进程定义为READY状态,这两种状态在linux下统一为 TASK_RUNNING状态。
S(TASK_UNINTERRUPTIBLE) 浅度睡眠态(即可中断的睡眠状态)
处于这个状态的进程因为等待某某事件的发生(比如等待socket连接、等待信号量),而被挂起。这些进程的task_struct结构被放入对应事件的等待队列中。当这些事件发生时(由外部中断触发、或由其他进程触发),对应的等待队列中的一个或多个进程将被唤醒。
通过ps命令我们会看到,一般情况下,进程列表中的绝大多数进程都处于TASK_INTERRUPTIBLE状态(除非机器的负载很高)。毕竟CPU就这么一两个,进程动辄几十上百个,如果不是绝大多数进程都在睡眠,CPU又怎么响应得过来。
D(TASK_UNINTERRUPTIBLE) 深度睡眠态(即不可中断的睡眠状态)
等待关键资源或者等待系统调用结束的时候会出现。
与TASK_INTERRUPTIBLE状态类似,进程也处于睡眠状态,但是此刻进程是不可中断的。不可中断,指的并不是CPU不响应外部硬件的中断,而是指进程不响应异步信号。 绝大多数情况下,进程处在睡眠状态时,总是应该能够响应异步信号的。否则你将惊奇的发现,`kill -9`竟然杀不死一个正在睡眠的进程了!于是我们也很好理解,为什么ps命令看到的进程几乎不会出现TASK_UNINTERRUPTIBLE状态,而总是 TASK_INTERRUPTIBLE状态。
T(Stopped) 暂停状态
进程暂停执行接受某种处理。如正在接受调试的进程处于这种状态,Linux 使用TASK_STOPPED 宏表示此状态。
当进程收到信号SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU时就会进入暂停状 态。可向其发送SIGCONT信号让进程转换到可运行状态。进程在调试期间接收到任何信号均会进入该状态。
当按Ctrl+z时,系统内核会向前台进程发送SIGSTOP信号,相似的,命令bg/fg使bash发送SIGCONT信号给进程。
事实上,直接在终端发送信号会使进程有相同的反应
$ kill -STOP PCB_NUM
$ kill -CONT PCB_NUM
Z (TASK_DEAD - EXIT_ZOMBIE)僵尸 状态
-
**孤儿进程:**一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
-
**僵尸进程:**一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
危害:
系统提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息, 就可以得到。这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。 但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放。 但这样就导致了问题,如果进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。
SIGCHLD
当一个子进程改变了它的状态时(停止运行,继续运行或者退出),有两件事会发生在父进程中:
- 得到 SIGCHLD 信号;
- waitpid() 或者 wait() 调用会返回。
其中子进程发送的 SIGCHLD 信号包含了子进程的信息,比如进程 ID、进程状态、进程使用 CPU 的时间等。
在子进程退出时,它的进程描述符不会立即释放,这是为了让父进程得到子进程信息,父进程通过 wait() 和 waitpid() 来获得一个已经退出的子进程的信息。
wait()
pid_t wait(int *status)
父进程调用 wait() 会一直阻塞,直到收到一个子进程退出的 SIGCHLD 信号,之后 wait() 函数会销毁子进程并返回。
如果成功,返回被收集的子进程的进程 ID;如果调用进程没有子进程,调用就会失败,此时返回 -1,同时 errno 被置为 ECHILD。
参数 status 用来保存被收集的子进程退出时的一些状态,如果对这个子进程是如何死掉的毫不在意,只想把这个子进程消灭掉,可以设置这个参数为 NULL。
waitpid()
pid_t waitpid(pid_t pid, int *status, int options)
作用和 wait() 完全相同,但是多了两个可由用户控制的参数 pid 和 options。
pid 参数指示一个子进程的 ID,表示只关心这个子进程退出的 SIGCHLD 信号。如果 pid=-1 时,那么和 wait() 作用相同,都是关心所有子进程退出的 SIGCHLD 信号。
options 参数主要有 WNOHANG 和 WUNTRACED 两个选项,WNOHANG 可以使 waitpid() 调用变成非阻塞的,也就是说它会立即返回,父进程可以继续执行其它任务。
孤儿进程
一个父进程退出,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。
孤儿进程将被 init 进程(进程号为 1)所收养,并由 init 进程对它们完成状态收集工作。
由于孤儿进程会被 init 进程收养,所以孤儿进程不会对系统造成危害。
僵尸进程
一个子进程的进程描述符在子进程退出时不会释放,只有当父进程通过 wait() 或 waitpid() 获取了子进程信息后才会释放。如果子进程退出,而父进程并没有调用 wait() 或 waitpid(),那么子进程的进程描述符仍然保存在系统中,这种进程称之为僵尸进程。
僵尸进程通过 ps 命令显示出来的状态为 Z(zombie)。
系统所能使用的进程号是有限的,如果产生大量僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程。
要消灭系统中大量的僵尸进程,只需要将其父进程杀死,此时僵尸进程就会变成孤儿进程,从而被 init 进程所收养,这样 init 进程就会释放所有的僵尸进程所占有的资源,从而结束僵尸进程。
性能监控
监控CPU
查看CPU使用率
$ sar -u
# eg:
$ sar -u 1 2
[/home/weber#]sar -u 1 2
Linux 2.6.35-22-generic-pae (MyVPS) 06/28/2014 _i686_ (1 CPU)
09:03:59 AM CPU %user %nice %system %iowait %steal %idle
09:04:00 AM all 0.00 0.00 0.50 0.00 0.00 99.50
09:04:01 AM all 0.00 0.00 0.00 0.00 0.00 100.00
后面的两个参数表示监控的频率,比如例子中的1和2,表示每秒采样一次,总共采样2次;
查看CPU平均负载
$ sar -q 1 2
sar指定-q后,就能查看运行队列中的进程数、系统上的进程大小、平均负载等;
查询内存
查看内存使用状况 sar指定-r之后,可查看内存使用状况;
$ sar -r 1 2
# 09:08:48 AM kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact
# 09:08:49 AM 17888 359784 95.26 37796 73272 507004 65.42 137400 150764
# 09:08:50 AM 17888 359784 95.26 37796 73272 507004 65.42 137400 150764
# Average: 17888 359784 95.26 37796 73272 507004 65.42 137400 150764
查看内存使用量
$ free -m
查询页面交换
查看页面交换发生状况 页面发生交换时,服务器的吞吐量会大幅下降;服务器状况不良时,如果怀疑因为内存不足而导致了页面交换的发生,可以使用sar -W这个命令来确认是否发生了大量的交换;
$ sar -W 1 3
查询硬盘使用
查看磁盘空间利用情况
$ df -h
查询当前目录下空间使用情况
$ du -sh
-h是人性化显示 s是递归整个目录的大小
查看该目录下所有文件夹的排序后的大小
$ for i in `ls`; do du -sh $i; done | sort
# 或者
$ du -sh `ls`
网络工具
查询网络服务和端口
netstat
命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Memberships) 等等。
列出所有端口 (包括监听和未监听的):
$ netstat -a
列出所有 tcp 端口:
$ netstat -at
列出所有有监听的服务状态:
$ netstat -l
使用netstat工具查询端口:
$ netstat -antp | grep 6379
# tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 25501/redis-server
$ ps 25501
# PID TTY STAT TIME COMMAND
# 25501 ? Ssl 28:21 ./redis-server ./redis.conf
eg. 查询7902端口现在运行什么程序
# 查询使用该端口的进程的PID;
$ lsof -i:7902
# COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
# WSL 30294 tuapp 4u IPv4 447684086 TCP 10.6.50.37:tnos-dp (LISTEN)
# 查到 30294 进程详情:
$ ps -fe | grep 30294
# tdev5 30294 26160 0 Sep10 ? 01:10:50 tdesl -k 43476
# root 22781 22698 0 00:54 pts/20 00:00:00 grep 11554
网络路由
查看路由状态:
$ route -n
发送ping包到地址IP:
$ ping IP
探测前往地址IP的路由路径:
$ traceroute IP
DNS查询,寻找域名domain对应的IP:
$ host domain
反向DNS查询:
$ host IP
镜像下载
直接下载文件或者网页:
$ wget url
常用选项:
- –limit-rate :下载限速
- -o:指定日志文件;输出都写入日志;
- -c:断点续传
ftp sftp lftp ssh
SSH登陆
$ ssh ID@host
ssh登陆远程服务器host,ID为用户名。
ftp/sftp文件传输
$ sftp ID@host
登陆服务器host,ID为用户名。sftp登陆后,可以使用下面的命令进一步操作:
get filename
# 下载文件put filename
# 上传文件ls
# 列出host上当前路径的所有文件cd
# 在host上更改当前路径lls
# 列出本地主机上当前路径的所有文件lcd
# 在本地主机更改当前路径
lftp同步文件夹(类似rsync工具)
$ lftp -u user:pass host
$ lftp user@host:~> mirror -n
网络复制
将本地localpath
指向的文件上传到远程主机的path
路径:
$ scp localpath ID@host:path
以ssh协议,遍历下载path
路径下的整个文件系统,到本地的localpath
:
$ scp -r ID@site:path localpath
用户管理工具
用户
添加用户
$ useradd -m username
该命令为用户创建相应的帐号和用户目录/home/username;
用户添加之后,设置密码:
密码以交互方式创建:
$ passwd username
删除用户
$ userdel -r username
不带选项使用 userdel只会删除用户,用户目录将仍会在/home目录下。要完全的删除用户信息,使用-r选项。
用户的组
将用户加入到组
添加用户操作也会相应的增加一个同名的组,用户属于同名组; 查看当前用户所属的组:
$ groups
一个用户可以属于多个组,将用户加入到组:
$ usermod -G groupNmame username
变更用户所属的根组(加入到新的组,并从原有的组中除去):
$ usermod -g groupName username
查看系统所有组
系统的所有用户及所有组信息分别记录在两个文件中:/etc/passwd , /etc/group 默认情况下这两个文件对所有用户可读:
查看所有用户及权限:
$ more /etc/passwd
查看所有的用户组及权限:
$ more /etc/group
环境变量
全局环境变量设定
/etc/profile
/etc/bashrc
用户目录下的私有环境变量设定
~/.profile
~/.bashrc
当登入系统获得一个shell进程时,其读取环境设置脚本分为三步:
- 读取
/etc/profile
,跟据其内容读取额外的文档,如/etc/profile.d
和/etc/inputrc
。 - 读取
~/.bash_profile
,其次读取~/.bash_login
,最后读取~/.profile
。 - 读取
~/.bashrc
。
~/.profile
与~/.bashrc
的区别:
- 这两者都具有个性化定制功能
~/.profile
可以设定本用户专有的路径,环境变量,等,它只能登入的时候执行一次~/.bashrc
也是某用户专有设定文档,可以设定路径,命令别名,每次shell script的执行都会使用它一次
设置自己经常进入的文件路径 和 命令的快捷方式:
# .bashrc
alias m='more'
log=/opt/applog/common_dir
# .bash_profile
export PS1='$PWD#'
通过上述设置,我们进入log目录就只需要输入cd $log即可;
系统管理
查询系统版本
查看Linux系统版本:
$ uname -a
$ lsb_release -a
查看Unix系统版本:操作系统版本:
$ more /etc/release
查询硬件信息
查看CPU使用情况:
$ sar -u 5 10
查询CPU信息:
$ cat /proc/cpuinfo
查看CPU的核的个数:
$ cat /proc/cpuinfo | grep processor | wc -l
查看内存信息:
$ cat /proc/meminfo
显示内存page大小(以KByte为单位):
$ pagesize
显示架构:
$ arch
设置系统时间
显示当前系统时间:
$ date