标签归档:LINUX

转载:Bash Shell 快速鍵

原文地址:http://blog.longwin.com.tw/2006/09/bash_hot_key_2006/

Alt-F: 到此行的後一個字

Alt-B: 到此行的前一個字
Ctrl-A: 回到此行最前面
Ctrl-E: 到此行的最後面
Ctrl-U: 清除一行中游標之前的所有文字
Ctrl-K: 清除一行字游標之後的所有文字
Ctrl-H: 移除游標前的一個字元(同 backspace)
Ctrl-D: 移除游標後的一個字元(若於命令列有字的話)
Ctrl-D: 結束輸入(如果您在 shell 下,就會跳出該 shell)
Ctrl-C: 終止正在執行的程式
Ctrl-Z: 暫時停止程式(將該工作放到背景) (fg 1, fg 2 拿回)
Ctrl-S: 停止輸出到畫面上(類似 Scroll Lock, ex: cat xxx 需暫停時使用)
Ctrl-Q: 回復輸出到畫面上(恢復Ctrl+S的輸出)
Ctrl-W: 刪除游標之前的最後一個單字
Ctrl-R: 搜尋過去的命令 (繼續往回找 Ctrl-r(上一個的上一個), 找過頭 Ctrl-R (Ctrl+Shift+r) 往下找)
Ctrl-F: 游標向後移動
Ctrl-B: 游標向前移動
Ctrl-P: 找上個指令(同上箭頭)
Ctrl-N: 找下個指令(同下箭頭)
Ctrl-T: 相近兩個字元互換位置
Ctrl-Z: 丟到背景執行, 可用 fg 回復
Ctrl-L: 清畫面
Ctrl-J: 同 Enter
Ctrl-I: 同 Tab
Ctrl-V: 加上要輸入特殊字元, ex: Ctrl-V Ctrl-C 會出現 ^C 而不是中斷
Ctrl-V TAB: 輸入 TAB,而不是命令列擴展
C-xC-e 可以使用 vim 寫入 script 讓他一次執行
Alt-d: 刪除游標之後的一個單字
TAB: 擴展要輸入的檔案到命令列上
上/下箭頭: 開始搜尋過去的命令
ESC-T: 最後 兩個 “單字” 互換位置
C-xC-e 可以使用 VIM 寫入 Script 讓他一次執行

Linux sort命令详解

用途

sort 命令对File 参数指定的文件中的行排序,并将结果写到标准输出。如果 File 参数指定多个文件,那么 sort 命令将这些文件连接起来,并当作一个文件进行排序。-(减号)代替文件名指定标准输入。如果您不指定任何文件名,那么该命令对标准输入排序。可以使用 -o 标志指定输出文件。如果不指定任何标志,sort 命令基于当前语言环境的整理顺序对输入文件的所有行排序。

基本用法

sort [OPTION]… [FILE]…

主要参数

-A 使用 ASCII 整理顺序代替当前语言环境的整理顺序在逐字节的基础上排序。
-b 忽略前导空格和制表符,找出字段的第一或最后列。
-c 检查输入是否已按照标志中指定的排序规则进行排序。如果输入文件排序不正确,就返回一个非零值。
-d 使用字典顺序排序。比较中仅考虑字母、数字和空格。
-f 比较前将所有小写字母改成大写字母。
-i 比较中忽略所有非显示字符。
-k KeyDefinition 指定排序关键字。KeyDefinition 选项的格式为:
[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]
排序关键字包括所有以 FStart 变量指定的字段和 CStart 变量指定的列开头的字符及以 FEnd 变量指定的字段和
CEnd 变量指定的列结束的字符。Modifier 变量的值可以是 b、d、f、i、n 或 r。修饰符与同一字母的标志等价。

-m 只合并多个输入文件;假设输入文件已经排序。
-n 按算术值对数字字段排序。数字字段可包含前导空格、可选减号、十进制数字、千分位分隔符和可选基数符。
对包含任何非数字字符的字段进行数字排序会出现无法预知的结果。
-o OutFile 将输出指向 OutFile 参数指定的文件,而不是标准输出。OutFile 参数值可以与 File 参数值相同。
-r 颠倒指定排序的顺序。
-t Character 指定 Character 为单一的字段分隔符。
-u 禁止按照排序关键字和选项的所有等同排序(每一组行中一行除外)。
-T Directory 将创建的所有临时文件放入 Directory 参数指定的目录中。
-y[Kilobytes] 用 Kilobytes 参数指定的主存储的千字节数启动 sort 命令,并根据需要增加存储量。
(如果 Kilobytes 参数指定的值小于最小存储站点或大于最大存储站点,就以这个最小存储站点或最大存储站点取代)。
如果省略 -y 标志,sort 命令以缺省的存储大小启动。
-y0 标志用最小存储启动,而 -y 标志(不带 Kilobytes 值)用最大存储启动。sort 命令使用的存储量显著地影响性能。
以大存储量对小文件排序将很浪费。
-z RecordSize 如果正在排序的任一行大于缺省的缓冲区大小,要防止出现异常终止。
指定 -c 或 -m 标志时,省略排序阶段,使用系统的缺省缓冲大小。如果已排序行超出这一大小,排序异常终止。
-z 选项指定排序阶段最长行的记录,因而可在合并阶段分配足够的缓冲区。
RecordSize 必须指明等于或大于要合并的最长行的字节值。

应用实例

要将包含大写字母和具有类似小写行的特殊字符行分组

sort -d -f fruits
-d 标志忽略特殊字符,-f 标志忽略大小写差异。

要除去重复行排序

sort -d -f -u fruits
-u 标志告诉 sort 命令除去重复的行,使文件中的每一行唯一

sort默认的排序方式是升序,如果想改成降序,就加个-r就搞定了。

使用-n选项,来告诉sort,“要以数值来排序”!

sort的-t选项和-k选项

sort提供了-t选项,后面可以设定间隔符。指定了间隔符之后,就可以用-k来指定列数了。

[rocrocket@rocrocket programming]$ sort -n -k 2 -t : facebook.txt
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3

参考资料

http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html

http://roclinux.cn/?p=1350

Linux的文件链接知识整理以及常用命令

Linux 的文件与目录

在 UNIX 系统中,操作系统为磁盘上的文本与图像、鼠标与键盘等输入设备及网络交互等 I/O 操作设计了一组通用 API,使他们被处理时均可统一使用字节流方式。换言之,UNIX 系统中除进程之外的一切皆是文件,而 Linux 保持了这一特性。为了便于文件的管理,Linux 还引入了目录(有时亦被称为文件夹)这一概念。目录使文件可被分类管理,且目录的引入使 Linux 的文件系统形成一个层级结构的目录树。Linux 与其他类 UNIX 系统一样并不区分文件与目录:目录是记录了其他文件名的文件。

什么是文件链接

文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。用户数据,即文件数据块 (data block),数据块是记录文件真实内容的地方;而元数据则是文件的附加属性,如文件大小、创建时间、所有者等信息。在 Linux 中,元数据中的 inode 号(inode 是文件元数据的一部分但其并不包含文件名,inode 号即索引节点号)才是文件的唯一标识而非文件名。为解决文件的共享使用,Linux 系统引入了两种链接:硬链接 (hard link) 与软链接(又称符号链接,即 soft link 或 symbolic link)。链接为 Linux 系统解决了文件的共享使用,还带来了隐藏文件路径、增加权限安全及节省存储等好处。

若一个 inode 号对应多个文件名,则称这些文件为硬链接。换言之,硬链接就是同一个文件使用了多个别名。

软链接与硬链接不同,若文件用户数据块中存放的内容是另一文件的路径名的指向,则该文件就是软连接。软链接就是一个普通文件,只是数据块内容有点特殊。软链接有着自己的 inode 号以及用户数据块

 

软连接VS 硬连接

  1. 1.软连接可以 跨文件系统 ,硬连接不可以.
  2. 2.关于 I节点的问题 。硬连接不管有多少个,都指向的是同一个I节点,会把 结点连接数增加,只要结点的连接数不是 0,文件就一直存在 ,不管你删除的是源文件还是连接的文件。只要有一个存在,文件就 存在(其实也不分什么 源文件连接文件的 ,因为他们指向都是同一个 I节点)。 当你修改源文件或者连接文件任何一个的时候,其他的 文件都会做同步的修改 。软链接不直接使用i节点号作为文件指针, 而是使用文件路径名作为指针。所以删除连接文件对源文件无影响,但是删除源文件,连接文件就会找不到要指向的文件。软链接有自己的inode, 并在磁盘上有一小片空间存放路径名。
  3. 3.软连接可以对一个不存在的文件名进行连接
  4. 4.软连接可以对目录进行连接

参考资料

学习 Linux,101: 创建和更改硬链接和符号链接

理解 Linux 的硬链接与软链接

LINUX 硬链接与软链接的区别

详解Linux操作系统中软硬链接的区别

Linux /dev下的那些特殊设备

/dev/null

/dev/null 它是空设备,也称为位桶(bit bucket)或者黑洞(black hole)。你可以向它输入任何数据,但任何写入它的数据都会被抛弃。通常用于处理不需要的输出流。(当然,它也可以作为空的输入流)

find / -name access_log 2>/dev/null
find命令在/目录下查找名为access_log的文件,并且错误输出不会显示出来(文件描述符2被重定向到/dev/null)

echo log > /dev/null 2>&1

 

> 代表重定向到哪里,例如:echo “123″ > /home/123.txt
1 表示stdout标准输出,系统默认值是1,所以”>/dev/null”等同于”1>/dev/null”
2 表示stderr标准错误
& 表示等同于的意思,2>&1,表示2的输出重定向等同于1

 

那么本文标题的语句:
1>/dev/null 首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,说白了就是不显示任何信息。
2>&1 接着,标准错误输出重定向等同于 标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。

 

/dev/zero 

/dev/zero 该设备无穷尽地提供空字符(ASCII NUL, 0×00),可以使用任何你需要的数目。它通常用于向设备或文件写入字符串0,用于初始化数据存储。(当然,也可作为输出流的接受容器) 

dd if=/dev/zero f=~/test.txt bs=1k count=1
产生1KB大小的文件~/text.txt

参考文档

http://www.51testing.com/html/38/225738-235339.html

http://blog.csdn.net/ithomer/article/details/9288353

http://www.cnblogs.com/chengmo/archive/2010/10/25/1857775.html

转载:lsof命令

原文地址 http://www.cnblogs.com/peida/archive/2013/02/26/2932972.html

lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。

1.命令格式:

lsof [参数][文件]

2.命令功能:

用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP、UDP)。找回/恢复删除的文件。是十分方便的系统监视工具,因为 lsof 需要访问核心内存和各种文件,所以需要root用户执行。

lsof打开的文件可以是:

1.普通文件

2.目录

3.网络文件系统的文件

4.字符或设备文件

5.(函数)共享库

6.管道,命名管道

7.符号链接

8.网络文件(例如:NFS file、网络socket,unix域名socket)

9.还有其它类型的文件,等等

3.命令参数:

-a 列出打开文件存在的进程

-c<进程名> 列出指定进程所打开的文件

-g  列出GID号进程详情

-d<文件号> 列出占用该文件号的进程

+d<目录>  列出目录下被打开的文件

+D<目录>  递归列出目录下被打开的文件

-n<目录>  列出使用NFS的文件

-i<条件>  列出符合条件的进程。(4、6、协议、:端口、 @ip )

-p<进程号> 列出指定进程号所打开的文件

-u  列出UID号进程详情

-h 显示帮助信息

-v 显示版本信息

4.使用实例:

实例1:无任何参数

命令:

lsof

输出:

[root@localhost ~]# lsof

COMMAND     PID USER   FD      TYPE             DEVICE     SIZE       NODE NAME
init          1 root  cwd       DIR                8,2     4096          2 /
init          1 root  rtd       DIR                8,2     4096          2 /
init          1 root  txt       REG                8,2    43496    6121706 /sbin/init
init          1 root  mem       REG                8,2   143600    7823908 /lib64/ld-2.5.so
init          1 root  mem       REG                8,2  1722304    7823915 /lib64/libc-2.5.so
init          1 root  mem       REG                8,2    23360    7823919 /lib64/libdl-2.5.so
init          1 root  mem       REG                8,2    95464    7824116 /lib64/libselinux.so.1
init          1 root  mem       REG                8,2   247496    7823947 /lib64/libsepol.so.1
init          1 root   10u     FIFO               0,17                1233 /dev/initctl
migration     2 root  cwd       DIR                8,2     4096          2 /
migration     2 root  rtd       DIR                8,2     4096          2 /
migration     2 root  txt   unknown                                        /proc/2/exe
ksoftirqd     3 root  cwd       DIR                8,2     4096          2 /
ksoftirqd     3 root  rtd       DIR                8,2     4096          2 /
ksoftirqd     3 root  txt   unknown                                        /proc/3/exe
migration     4 root  cwd       DIR                8,2     4096          2 /
migration     4 root  rtd       DIR                8,2     4096          2 /
migration     4 root  txt   unknown                                        /proc/4/exe
ksoftirqd     5 root  cwd       DIR                8,2     4096          2 /
ksoftirqd     5 root  rtd       DIR                8,2     4096          2 /
ksoftirqd     5 root  txt   unknown                                        /proc/5/exe
events/0      6 root  cwd       DIR                8,2     4096          2 /
events/0      6 root  rtd       DIR                8,2     4096          2 /
events/0      6 root  txt   unknown                                        /proc/6/exe
events/1      7 root  cwd       DIR                8,2     4096          2 /

说明:

lsof输出各列信息的意义如下:

COMMAND:进程的名称

PID:进程标识符

PPID:父进程标识符(需要指定-R参数)

USER:进程所有者

PGID:进程所属组

FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等

(1)cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改

(2)txt :该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序

(3)lnn:library references (AIX);

(4)er:FD information error (see NAME column);

(5)jld:jail directory (FreeBSD);

(6)ltx:shared library text (code and data);

(7)mxx :hex memory-mapped type number xx.

(8)m86:DOS Merge mapped file;

(9)mem:memory-mapped file;

(10)mmap:memory-mapped device;

(11)pd:parent directory;

(12)rtd:root directory;

(13)tr:kernel trace file (OpenBSD);

(14)v86  VP/ix mapped file;

(15)0:表示标准输出

(16)1:表示标准输入

(17)2:表示标准错误

一般在标准输出、标准错误、标准输入后还跟着文件状态模式:r、w、u等

(1)u:表示该文件被打开并处于读取/写入模式

(2)r:表示该文件被打开并处于只读模式

(3)w:表示该文件被打开并处于

(4)空格:表示该文件的状态模式为unknow,且没有锁定

(5)-:表示该文件的状态模式为unknow,且被锁定

同时在文件状态模式后面,还跟着相关的锁

(1)N:for a Solaris NFS lock of unknown type;

(2)r:for read lock on part of the file;

(3)R:for a read lock on the entire file;

(4)w:for a write lock on part of the file;(文件的部分写锁)

(5)W:for a write lock on the entire file;(整个文件的写锁)

(6)u:for a read and write lock of any length;

(7)U:for a lock of unknown type;

(8)x:for an SCO OpenServer Xenix lock on part      of the file;

(9)X:for an SCO OpenServer Xenix lock on the      entire file;

(10)space:if there is no lock.

TYPE:文件类型,如DIR、REG等,常见的文件类型

(1)DIR:表示目录

(2)CHR:表示字符类型

(3)BLK:块设备类型

(4)UNIX: UNIX 域套接字

(5)FIFO:先进先出 (FIFO) 队列

(6)IPv4:网际协议 (IP) 套接字

DEVICE:指定磁盘的名称

SIZE:文件的大小

NODE:索引节点(文件在磁盘上的标识)

NAME:打开文件的确切名称

实例2:查看谁正在使用某个文件,也就是说查找某个文件相关的进程

命令:

lsof /bin/bash

输出:

[root@localhost ~]# lsof /bin/bash
COMMAND   PID USER  FD   TYPE DEVICE   SIZE    NODE NAME
bash    24159 root txt    REG    8,2 801528 5368780 /bin/bash
bash    24909 root txt    REG    8,2 801528 5368780 /bin/bash
bash    24941 root txt    REG    8,2 801528 5368780 /bin/bash
[root@localhost ~]#

说明:

实例3:递归查看某个目录的文件信息

命令:

lsof test/test3

输出:

[root@localhost ~]# cd /opt/soft/
[root@localhost soft]# lsof test/test3
COMMAND   PID USER   FD   TYPE DEVICE SIZE    NODE NAME
bash    24941 root  cwd    DIR    8,2 4096 2258872 test/test3
vi      24976 root  cwd    DIR    8,2 4096 2258872 test/test3
[root@localhost soft]#

说明:使用了+D,对应目录下的所有子目录和文件都会被列出

实例4:不使用+D选项,遍历查看某个目录的所有文件信息的方法

命令:

lsof |grep ‘test/test3′

输出:

[root@localhost soft]# lsof |grep ‘test/test3′

bash      24941 root  cwd       DIR                8,2     4096    2258872 /opt/soft/test/test3
vi        24976 root  cwd       DIR                8,2     4096    2258872 /opt/soft/test/test3
vi        24976 root    4u      REG                8,2    12288    2258882 /opt/soft/test/test3/.log2013.log.swp
[root@localhost soft]#

 

实例5:列出某个用户打开的文件信息

命令:

lsof -u username

说明:

-u 选项,u其实是user的缩写

实例6:列出某个程序进程所打开的文件信息

命令:

lsof -c mysql

说明:

-c 选项将会列出所有以mysql这个进程开头的程序的文件,其实你也可以写成 lsof | grep mysql, 但是第一种方法明显比第二种方法要少打几个字符了

实例7:列出多个进程多个打开的文件信息

命令:

lsof -c mysql -c apache

实例8:列出某个用户以及某个进程所打开的文件信息

命令:

lsof  -u test -c mysql

说明:

用户与进程可相关,也可以不相关

实例9:列出除了某个用户外的被打开的文件信息

命令:

lsof -u ^root

说明:

^这个符号在用户名之前,将会把是root用户打开的进程不让显示

实例10:通过某个进程号显示该进行打开的文件

命令:

lsof -p 1

实例11:列出多个进程号对应的文件信息

命令:

lsof -p 1,2,3

实例12:列出除了某个进程号,其他进程号所打开的文件信息

命令:

lsof -p ^1

实例13:列出所有的网络连接

命令:

lsof -i

实例14:列出所有tcp 网络连接信息

命令:

lsof -i tcp

实例15:列出所有udp网络连接信息

命令:

lsof -i udp

实例16:列出谁在使用某个端口

命令:

lsof -i :3306

实例17:列出谁在使用某个特定的udp端口

命令:

lsof -i udp:55

或者:特定的tcp端口

命令:

lsof -i tcp:80

实例18:列出某个用户的所有活跃的网络端口

命令:

lsof -a -u test -i

实例19:列出所有网络文件系统

命令:

lsof -N

实例20:域名socket文件

命令:

lsof -u

实例21:某个用户组所打开的文件信息

命令:

lsof -g 5555

实例22:根据文件描述列出对应的文件信息

命令:

lsof -d description(like 2)

例如:lsof  -d  txt

例如:lsof  -d  1

例如:lsof  -d  2

说明:

0表示标准输入,1表示标准输出,2表示标准错误,从而可知:所以大多数应用程序所打开的文件的 FD 都是从 3 开始

实例23:根据文件描述范围列出文件信息

命令:

lsof -d 2-3

实例24:列出COMMAND列中包含字符串" sshd",且文件描符的类型为txt的文件信息

命令:

lsof -c sshd -a -d txt

输出:

[root@localhost soft]# lsof -c sshd -a -d txt
COMMAND   PID USER  FD   TYPE DEVICE   SIZE    NODE NAME
sshd     2756 root txt    REG    8,2 409488 1027867 /usr/sbin/sshd
sshd    24155 root txt    REG    8,2 409488 1027867 /usr/sbin/sshd
sshd    24905 root txt    REG    8,2 409488 1027867 /usr/sbin/sshd
sshd    24937 root txt    REG    8,2 409488 1027867 /usr/sbin/sshd

实例25:列出被进程号为1234的进程所打开的所有IPV4 network files

命令:

lsof -i 4 -a -p 1234

实例26:列出目前连接主机peida.linux上端口为:20,21,22,25,53,80相关的所有文件信息,且每隔3秒不断的执行lsof指令

命令:

lsof -i @peida.linux:20,21,22,25,53,80  -r  3

iftop的安装和使用

说明

iftop工具主要用来显示本机网络流量情况及各相互通信的流量集合,如单独同哪台机器间的流量大小,非常适合于代理服务器和iptables服务器使用,这样可以方便的查看各客户端流量情况。iftop可以在类Unix系统中可以使用top查看系统资源、进程、内存占用等信息。查看网络状态可以使用netstat、nmap等工具。若要查看实时的网络流量,监控TCP/IP连接等,则可以使用iftop。

安装

sudo yum install iftop

使用

-i设定监测的网卡,如:# iftop -i eth1

-B 以bytes为单位显示流量(默认是bits),如:# iftop -B

-n使host信息默认直接都显示IP,如:# iftop -n

-N使端口信息默认直接都显示端口号,如: # iftop -N

-F显示特定网段的进出流量,如# iftop -F 10.10.1.0/24或# iftop -F 10.10.1.0/255.255.255.0

-h(display this message),帮助,显示参数信息

-p使用这个参数后,中间的列表显示的本地主机信息,出现了本机以外的IP信息;

-b使流量图形条默认就显示;

-f这个暂时还不太会用,过滤计算包用的;

-P使host信息及端口信息默认就都显示;

-m设置界面最上边的刻度的最大值,刻度分五个大段显示,例:# iftop -m 100M

进入iftop画面后的一些操作命令(注意大小写)

按h切换是否显示帮助;

按n切换显示本机的IP或主机名;

按s切换是否显示本机的host信息;

按d切换是否显示远端目标主机的host信息;

按t切换显示格式为2行/1行/只显示发送流量/只显示接收流量;

按N切换显示端口号或端口服务名称;

按S切换是否显示本机的端口信息;

按D切换是否显示远端目标主机的端口信息;

按p切换是否显示端口信息;

按P切换暂停/继续显示;

按b切换是否显示平均流量图形条;

按B切换计算2秒或10秒或40秒内的平均流量;

按T切换是否显示每个连接的总流量;

按l打开屏幕过滤功能,输入要过滤的字符,比如ip,按回车后,屏幕就只显示这个IP相关的流量信息;

按L切换显示画面上边的刻度;刻度不同,流量图形条会有变化;

按j或按k可以向上或向下滚动屏幕显示的连接记录;

按1或2或3可以根据右侧显示的三列流量数据进行排序;

按<根据左边的本机名或IP排序;

按>根据远端目标主机的主机名或IP排序;

按o切换是否固定只显示当前的连接;

按f可以编辑过滤代码,这是翻译过来的说法,我还没用过这个!

按!可以使用shell命令,这个没用过!没搞明白啥命令在这好用呢!

按q退出监控。

TX:发送流量
RX:接收流量
TOTAL:总流量
Cumm:运行iftop到目前时间的总流量
peak:流量峰值
rates:分别表示过去 2s 10s 40s 的平均流量

 

 

参考资料

iftop流量監控使用教學,立刻抓出吃流量兇手

Linux流量监控工具 – iftop (最全面的iftop教程)

How to install iftop on Linux

《构建高性能WEB站点》读书笔记——Part1

数据如何发送

说到数据的发送,也就是数据从主机进入线路的这段旅程,一般要经过以下几个环节。

  1. 应用程序首先得将要发送的数据写入该进程的内存地址空间中,熟悉网络编程的开发者对这个环节一定非常熟悉,通常在程序开发中这只需要一般的运行时变量赋值即可。
  2. 应用程序通过系统函数库接口(比如send函数)向内核发出系统调用,由系统内核来进行随后的操作,它将这些数据从用户态内存区复制到由内核维护的一段称为内核缓冲区的内存地址空间。这块地址空间的大小通常是有限的,所有要发送的数据以队列的形式进入这里,这些数据可能来自于多个进程,每块数据都有一个额外的标记号来标记他的去向。如果要发送的数据比较多,那么该系统调用需要多次进行,每次复制一定的数据大小,这个大小取决于网络数据包的大小以及内核缓冲区的承载能力。重复的熊调用体现在应用编程层面重复调用send函数。
  3. 当数据写入内核缓冲区后,内核会通知网卡控制器起来取数据,同时CPU转而处理其他进程。网卡控制器接到通知后,便根据网卡驱动信息得知对应内核缓冲区的地址,将要发送的数据复制到网卡的缓冲区中。注意在以上一系列的数据复制中,数据始终按照连接两端设备的内部总线宽度来复制,也就是字节的整数倍。比如在32位总线的主机系统中,采用PCI-X总线接口的网卡一般使用32位总线宽度,那么从内核缓冲区到网卡缓冲区的数据复制过程中,任何时刻只能复制32位的比特信息。
  4. 网卡缓冲区的数据需要发送到线路中,同事释放缓冲区来获取更多要发送的数据。但是我们知道,只有二进制的数据信号才可以在线路中传输,所以这时候需要对数据进行字节到位的转换,这种转换不难想象,就是将数据的每个位按照顺序依次发出。
  5. 发送时,网卡会使用内部特定的物理装置来生成可以传播的各种信号,比如在使用铜线线路时,网卡会根据"0"和"1"的变化发生不同的电信号;而使用光纤线路时,网卡会产生不同的光信号。

服务器并发处理能力

通常所讲的最大并发数是有一定利益前提的,那就是服务器和用户双方锁期待的最大收益,服务器希望支持高并发数及高吞吐率,而用户不管那么多,只希望等待较少的时间,或者得到更快的下载速度,显然,双方不可能都彻底满足,所以便存在讨价还价的余地,同事双方也都有能够忍受的最低尺度。

从某种意义上可以说,WEB服务器所做的工作的本质就是,争取以最快的速度将内核缓冲区中的用户请求一个不剩地都拿回来,然后尽最大努力同时快速处理完这些请求,并将响应数据放到内核维护的另一块用于发送数据的缓冲区中,接下来再尽快处理下一波请求,并尽量让客户请求在内核缓冲区中不要等太久。

用户平均请求等待时间主要用于衡量服务器在一定并发用户的情况下,对于单个用户的服务质量;而服务期平均请求处理时间与前者相比,则用于衡量服务器的整体服务质量,它其实就是吞吐率的倒数。

并发策略的设计就是服务器同时处理较多请求的时候,如何处理协调充分利用CPU和IO操作,使其在较大用户数的情况下提供较高的吞吐率。

进程的优先级属性为Priority,在Top结果中用PR表示,而优先级动态调整至在Top中用NI表示。PR所代表的值有什么含义呢?它其实就是进程调度器分配给进程的时间片长度,单位是时钟的个数,那么一个时钟需要多长时间呢?这跟CPU的主频及操作系统平台有关,比如LINUX上一般为10ms,那么PR值为15表示这个进程的时间片为150MS.

IOWAIT往往并不能真实地代表I/O操作的性能或者工作量,它的涉及出发点是用来衡量CPU的性能,举个例子,假如有一个任务话费10MS的IO操作时间和10MS的CPU时间,那么总时间为20MS,IOWait便为10ms/20ms,等于50%,这是并不一定意味着IO操作的繁忙程度为50%,事实上,即便是IOWait为100%,也不一定代表I/O出现性能问题或者瓶颈,同样,IOWait为0的时候I/O操作也可能很繁忙,所以,如果你希望真正了解I/O性能,可以进行磁盘I/O测试护着查看网络I/O流量。

系统调用

用户态和内核态的分离,动机主要在于提高系统底层安全性以及简化开发模型。由于所有进程都必须通过内核提供的系统调用来操作硬件,所以不用担心应用程序对硬件进行非法操作,由于将底层的实现都屏蔽在了系统调用中,也大大简化了用户态应用开发的难度。系统调用涉及进程从用户态到内核态的切换,导致一定的内存空间的交换,这也是一定程度的上的上下文切换,所以系统调用的开销通常认为是比较昂贵的。减少不必要的系统调用,也是WEB服务器性能优化的一个方面。

IO模型

同步阻塞IO是指当进程调用某些涉及I/O操作的系统调用或库函数时,比如accept()、send()、recv()等,进程便暂停下来,等待I/O操作完成再继续运行。这是一种简单而有效的I/O模型,它可以和多进程结合起来有效地利用CPU资源,但是其代价就是多进程的大量内存开销。

同步非阻塞I/O的调用不会等待数据的就绪,如果数据不可读或者不可写,它会立即告诉进程。比如我们使用非阻塞recv()接收网络数据的时候,如果网卡缓冲区中没有可接收的数据,函数就及时返回,告诉进程没有数据可读了。相比于阻塞I/O,这种非阻塞I/O结合反复轮询来尝试数据是否就绪,防止进程被阻塞,最大的好处便在于可以一个进程里同时处理多个I/O操作。但正是由于需要进程执行多次的轮询来查看数据是否就绪,这花费了大量的CPU时间,使得进程处于忙碌等待状态。

多路I/O就绪通知的出现,提供了对大量文件描述符就绪检查的高性能方案,它允许进程通过一种方式来同时监控所有文件描述符,并可以快速获得所有就绪的文件描述符,然后,只针对这些文件描述符进行数据访问。

select系统调用用来监控包含多个文件描述符的数组,当select()返回后,该数组就绪的文件描述符便会被内核修改标志位,使得该进程可以获得这些文件描述符从而进行后续的读写操作。select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大,期复制的开销也线性增长。同时网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()会对所有socket进行一次线性扫描。

poll和select在本质上没有多大差别,但poll没有最大文件描述符数量的限制。poll有着和select同样的缺点。select()和poll()将就绪的文件描述符告诉进程后,如果进程美欧对其进行I/O操作,那么下次select()或者poll()的时候将再次报告这些文件描述符,所以它们一般不会丢失就绪消息,这种方式称为水平触发。

epoll采用基于事件的就绪通知方式。在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事先通过epoll_ctl()来注册每一个文件描述符,一旦某个文件描述符就绪是,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知。

内存映射

LINUX内核提供一种访问磁盘文件的特殊方式,它可以将内存中某块地址空间和我们要指定的磁盘文件相关联,从而我们对这块内存的访问转换为对磁盘文件的访问,这种技术称为内存映射。在大多数情况下,使用内存映射可以提高磁盘IO的性能,它无需使用read或writ等系统调用来访问文件,而是通过mmap系统调用来建立内存和磁盘文件的关联,然后像访问内存一样自由的访问文件。有两种类型的内存映射,共享型和私有型,前者可以将任何对内存的写操作都同步到磁盘文件,而且所有映射同一个文件的进程都共享一个进程对映射内存的修改;后者映射的文件只能是只读文件,所以不可能将对内存的写同步到文件,而且多个进程不共享修改。显然,共享型内存映射的效率偏低,因为如果一个文件被限制多进程映射,那么每次的修改同步将花费一定的开销。

在LINUX2.6中,内存映射和直接访问文件没有本质上的差异,因为数据从进程用户态内存空间到磁盘都要经过两次复制,即在磁盘与内核缓冲区之间以及在内内核缓冲区与用户态内存空间。

引入内核缓冲区的目的在于提高磁盘文件的访问性能,因为当进程需要读取磁盘文件时,如果文件内容已经在内核缓冲区中,那么就不需要再次访问磁盘。而当进程需要向文件中写入数据时,实际上只是写到内核缓冲区便告诉进程已经写入成功,而真正写入磁盘是通过一定的策略进行延迟的。

对于一些较复杂的应用,比如数据库服务器,他们为饿了充分提高性能,希望绕过内核缓冲区,由自己在用户态空间实现并管理管理IO缓冲区,包括缓存机制以及延迟机制等。另外,绕过内核缓冲区也可以减少系统内存的开销,因为内存缓冲区本身就在使用系统内容。

LINUX提供了对这种需求的支持,即在open系统调用中增加参数选项O_DIRECT,用它打开看到文件便可以绕过内核缓冲区直接访问,这样便有效的避免了CPU和内存的多余时间开销。O_SYNC选项只对写数据有效,它将写入内核缓冲区的数据立即写入磁盘,将机器故障时数据的丢失减少到最小,但它还是要经过内核缓冲区的。

sendfile系统调用可以将磁盘文件的特定部分直接传送到代表客户端的socket描述符,加快了静态文件和请求速度,同时也减少了CPU和内存的开销。

linux命令-strace

参数

-c 统计每一系统调用的所执行的时间,次数和出错的次数等.
-d 输出strace关于标准错误的调试信息.
-f 跟踪由fork调用所产生的子进程.
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.
-h 输出简要的帮助信息.
-i 输出系统调用的入口指针.
-q 禁止输出关于脱离的消息.
-r 打印出相对时间关于,,每一个系统调用.
-t 在输出中的每一行前加上时间信息.
-tt 在输出中的每一行前加上时间信息,微秒级.
-ttt 微秒级输出,以秒了表示时间.
-T 显示每一调用所耗的时间.
-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.
-V 输出strace的版本信息.
-x 以十六进制形式输出非标准字符串
-xx 所有字符串以十六进制形式输出.
-a column
设置返回值的输出位置.默认 为40.
-e expr
指定一个表达式,用来控制如何跟踪.格式如下:
[qualifier=][!]value1[,value2]…
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用来限定的符号或数字.默认的 qualifier是 trace.感叹号是否定符号.例如:
-eopen等价于 -e trace=open,表示只跟踪open调用.而-etrace!=open表示跟踪除了open以外的其他调用.有两个特殊的符号 all 和 none.
注意有些shell使用!来执行历史记录里的命令,所以要使用\\.
-e trace=set
只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all.
-e trace=file
只跟踪有关文件操作的系统调用.
-e trace=process
只跟踪有关进程控制的系统调用.
-e trace=network
跟踪与网络有关的所有系统调用.
-e strace=signal
跟踪所有与系统信号有关的 系统调用
-e trace=ipc
跟踪所有与进程通讯有关的系统调用
-e abbrev=set
设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all.
-e raw=set
将指 定的系统调用的参数以十六进制显示.
-e signal=set
指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.
-e read=set
输出从指定文件中读出 的数据.例如:
-e read=3,5
-e write=set
输出写入到指定文件中的数据.
-o filename
将strace的输出写入文件filename
-p pid
跟踪指定的进程pid.
-s strsize
指定输出的字符串的最大长度.默认为32.文件名一直全部输出.
-u username
以username 的UID和GID执行被跟踪的命令

使用

限制strace只跟踪特定的系统调用

strace -f -o configure-strace.txt -e execve ./configure

获取指定进程的系统调用的统计信息

strace –c –o output.txt  -p 10011

获取指定进程的系统调用记录

strace –T –o output.txt  -p 10011

参考资料

Linux strace命令

 

使用strace工具故障排查的5种简单方法

找出一个程序启动时读取了哪个配置文件

为什么程序没有打开我的文件?

进程此刻正在做什么?

程序的时间花在什么地方

为什么我不能连接到服务器?

Sudo

概述

它的特性主要有这样几点:

§ Sudo能够限制用户只在某台主机上运行某些命令。

§ Sudo提供了丰富的日志,详细地记录了每个用户干了什么。它能够将日志传到中心主机或者日志服务器。

§ Sudo使用时间戳文件来执行类似的“检票”系统。当用户调用sudo并且输入它的密码时,用户获得了一张存活期为5分钟的票(这个值可以在编译的时候改变)。

§ Sudo的配置文件是sudoers文件,它允许系统管理员集中的管理用户的使用权限和使用的主机。它所存放的位置默认是在/etc/sudoers,属性必须为0440。

sudo于1980年前后被写出之前,一般用户管理系统的方式是利用su切换为超级用户。但是使用su的缺点之一在于必须要先告知超级用户的密码。sudo使一般用户不需要知道超级用户的密码即可获得权限。首先超级用户将普通用户的名字、可以执行的特定命令、按照哪种用户或用户组的身份执行等信息,登记在特殊的文件中(通常是/etc/sudoers),即完成对该用户的授权(此时该用户称为“sudoer”);在一般用户需要取得特殊权限时,其可在命令前加上“sudo”,此时sudo将会询问该用户自己的密码(以确认终端机前的是该用户本人),回答后系统即会将该命令的进程以超级用户的权限运行。之后的一段时间内(默认为5分钟,可在/etc/sudoers自定义),使用sudo不需要再次输入密码。

由于不需要超级用户的密码,部分Unix系统甚至利用sudo使一般用户取代超级用户作为管理帐号,例如UbuntuMac OS X等。

语法

sudo [ -Vhl LvkKsHPSb ] │ [ -p prompt ] [ -c class│- ] [ -a auth_type ] [-u username│#uid ] command

参数
-V 显示版本编号
-h 会显示版本编号及指令的使用方式说明
-l 显示出自己(执行 sudo 的使用者)的权限
-v 因为 sudo 在第一次执行时或是在 N 分钟内没有执行(N 预设为五)会问密码,这个参数是重新做一次确认,如果超过 N 分钟,也会问密码
-k 将会强迫使用者在下一次执行 sudo 时问密码(不论有没有超过 N 分钟)
-b 将要执行的指令放在背景执行
-p prompt 可以更改问密码的提示语,其中 %u 会代换为使用者的帐号名称, %h 会显示主机名称
-u username/#uid 不加此参数,代表要以 root 的身份执行指令,而加了此参数,可以以 username 的身份执行指令(#uid 为该 username 的使用者号码)
-s 执行环境变数中的 SHELL 所指定的 shell ,或是 /etc/passwd 里所指定的 shell
-H 将环境变数中的 HOME (家目录)指定为要变更身份的使用者家目录(如不加 -u 参数就是系统管理者 root )
command 要以系统管理者身份(或以 -u 更改为其他人)执行的指令

范例

1. sudo -l 列出目前的权限

若用户不在sudoers中会提示不能运行sudo命令,存在则会显示详细的权限。

2. sudo -V 列出 sudo 的版本资讯

3. 指令名称:sudoers(在fc5下显示不能找到此命令,但用man可以查到其用法。)用来显示可以使用sudo的用户

 

Sudo的权限验证过程

 

参考资料

sudo

Sudo提权验证流程