Linux基础总结

Linux操做系统

Linux操做系统博大精深,其中对线程,IO,文件系统等概念的实现都颇有借鉴意义。html

文件系统和VFS

文件系统的inode上面讲过了。VFS主要用于屏蔽底层的不一样文件系统,好比接入网络中的nfs文件系统,亦或是windows文件系统,正常状况下难以办到,而vfs经过使用IO操做的posix规范来规定全部文件读写操做,每一个文件系统只须要实现这些操做就能够接入VFS,不须要从新安装文件系统。node

进程和线程

> 进程、程序与线程
> 
> 程序
> 
>  程序,简单的来讲就是存在磁盘上的二进制文件,是能够内核所执行的代码 
> 
> 进程
> 
>  当一个用户启动一个程序,将会在内存中开启一块空间,这就创造了一个进程,一个进程包含一个独一无二的PID,和执行者的权限属性参数,以及程序所需代码与相关的资料。
>  进程是系统分配资源的基本单位。
>  一个进程能够衍生出其余的子进程,子进程的相关权限将会沿用父进程的相关权限。
> 
> 线程
> 
>  每一个进程包含一个或多个线程,线程是进程内的活动单元,是负责执行代码和管理进程运行状态的抽象。
>  线程是独立运行和调度的基本单位。
复制代码

子进程和父进程 进程的层次结构(父进程与子进程)在进程执行的过程当中可能会衍生出其余的进程,称之为子进程,子进程拥有一个指明其父进程PID的PPID。子进程能够继承父进程的环境变量和权限参数。linux

因而,linux系统中就诞生了进程的层次结构——进程树。 进程树的根是第一个进程(init进程)。ios

过程调用的流程: fork & exec一个进程生成子进程的过程是,系统首先复制(fork)一份父进程,生成一个暂存进程,这个暂存进程和父进程的区别是pid不同,并且拥有一个ppid,这时候系统再去执行(exec)这个暂存进程,让他加载实际要运行的程序,最终成为一个子进程的存在。正则表达式

服务与进程算法

简单的说服务(daemon)就是常驻内存的进程,一般服务会在开机时经过init.d中的一段脚本被启动。shell

进程通讯数据库

进程通讯的几种基本方式:管道,信号量,消息队列,共享内存,快速用户控件互斥。express

fork方法

一个进程,包括代码、数据和分配给进程的资源。fork()函数经过系统调用建立一个与原来进程几乎彻底相同的进程,编程

也就是两个进程能够作彻底相同的事,但若是初始参数或者传入的变量不一样,两个进程也能够作不一样的事。

一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。而后把原来的进程的全部值都
复制代码

复制到新的新进程中,只有少数值与原来的进程的值不一样。至关于克隆了一个本身。

fork调用的一个奇妙之处就是它仅仅被调用一次,却可以返回两次,它可能有三种不一样的返回值:
    1)在父进程中,fork返回新建立子进程的进程ID;
    2)在子进程中,fork返回0;
    3)若是出现错误,fork返回一个负值;
复制代码

如何理解pid在父子进程中不一样?

其实就至关于链表,进程造成了链表,父进程的pid指向了子进程的pid,由于子进程没有子进程,因此pid为0。

写时复制

传统的fork机制是,调用fork时,内核会复制全部的内部数据结构,复制进程的页表项,而后把父进程的地址空间按页复制给子进程(很是耗时)。

现代的fork机制采用了一种惰性算法的优化策略。

为了不复制时系统开销,就尽量的减小“复制”操做,当多个进程须要读取他们本身那部分资源的副本时,并不复制多个副本出来,而是为每一个进程设定一个文件指针,让它们读取同一个实际文件。

显然这样的方式会在写入时产生冲突(相似并发),因而当某个进程想要修改本身的那个副本时,再去复制该资源,(只有写入时才复制,因此叫写时复制)这样就减小了复制的频率。
复制代码

父子进程,僵尸进程,孤儿进程,守护进程

父进程经过fork产生子进程。

孤儿进程:当子进程未结束时父进程异常退出,本来须要由父进程进行处理的子进程变成了孤儿进程,init系统进程会把这些进程领养,避免他们成为孤儿。

僵尸进程:当子进程结束时,会在内存中保留一部分数据结构等待父亲进程显式结束,若是父进程没有执行结束操做,则会致使子进程的剩余结构没法被释放,占用空间形成严重后果。

守护进程:守护进程用于监控其余进程,当发现大量僵尸进程时,会找到他们的父节点并杀死,同时让init线程认养他们以便释放这些空间。

僵尸进程是有害的,孤儿进程因为内核进程的认养不会形成危害。

进程组和会话

会话和进程组进程组每一个进程都属于某个进程组,进程组就是由一个或者多个为了实现做业控制而相互关联的进程组成的。

一个进程组的id是进程组首进程的pid(若是一个进程组只有一个进程,那进程组和进程其实没啥区别)。

进程组的意义在于,信号能够发送给进程组中的全部进程。这样能够实现对多个进程的同时操做。 会话会话是一个或者多个进程组的集合。

通常来讲,会话(session)和shell没有什么本质上的区别。 咱们一般使用用户登陆一个终端进行一系列操做这样的例子来描述一次会话。

举例

$cat ship-inventory.txt | grep

booty|sort上面就是在某次会话中的一个shell命令,它会产生一个由3个进程组成的进程组。

守护进程

守护进程(服务)守护进程(daemon)运行在后台,不与任何控制终端相关联。一般在系统启动时经过init脚本被调用而开始运行。

在linux系统中,守护进程和服务没有什么区别。 对于一个守护进程,有两个基本的要求:其一:必须做为init进程的子进程运行,其二:不与任何控制终端交互。

硬链接和软链接

硬连接指的是不一样的文件名指向同一个inode节点,好比某个目录下的a和另外一个目录下的b,创建一个软链接让a指向b,则a和b共享同一个inode。

软链接是指一个文件的inode节点不存数据,而是存储着另外一个文件的绝对路径,访问文件内容时其实是去访问对应路径下的文件inode,这样的话文件发生改动或者移动都会致使软链接失效。

线程

线程基础概念线程是进程内的执行单元(比进程更低一层的概念),具体包括 虚拟处理器,堆栈,程序状态等。 能够认为 线程是操做系统调度的最小执行单元。

现代操做系统对用户空间作两个基础抽象:虚拟内存和虚拟处理器。这使得进程内部“感受”本身独占机器资源。

虚拟内存系统会为每一个进程分配独立的内存空间,这会让进程觉得本身独享所有的RAM。

可是同一个进程内的全部线程共享该进程的内存空间。 虚拟处理器这是一个针对线程的概念,它让每一个线程都“感受”本身独享CPU。实际上对于进程也是同样的。

线程模型

线程模型线程的概念同时存在于内核和用户空间中。下面介绍三种线程模型。

内核级线程模型每一个内核线程直接转换成用户空间的线程。即内核线程:用户空间线程=1:1

用户级线程模型这种模型下,一个保护了n个线程的用户进程只会映射到一个内核进程。即n:1。
能够减小上下文切换的成本,但在linux下没什么意义,由于linux下进程间的上下文切换自己就没什么消耗,因此不多使用。

混合式线程模型上述两种模型的混合,即n:m型。
很难实现。
复制代码

内核线程实现

系统线程实现:PThreads 原始的linux系统调用中,没有像C++11或者是Java那样完整的线程库。

总体看来pthread的api比较冗余和复杂,可是基本操做也主要是 建立、退出等。

1.建立线程

int pthread_create
  
  (若线程建立成功,则返回0。若线程建立失败,则返回出错编号)
  
  注意:线程建立者和新建线程之间没有fork()调用那样的父子关系,它们是对等关系。调用pthread_create()建立线程后,线程建立者和新建线程哪一个先运行是不肯定的,特别是在多处理机器上。
复制代码

   2.终止线程

void pthread_exit(void *value_ptr);
  
     线程调用pthread_exit()结束本身,参数value_ptr做为线程的返回值被调用pthread_join的线程使用。因为一个进程中的多个线程是共享数据段的,所以一般在线程退出以后,退出线程所占用的资源并不会随着线程的终止而获得释放,可是能够用pthread_join()函数来同步并释放资源
复制代码

3.取消线程

int pthread_cancel(pthread_t thread);
  
  注意:如果在整个程序退出时,要终止各个线程,应该在成功发送 CANCEL指令后,使用 pthread_join函数,等待指定的线程已经彻底退出之后,再继续执行;不然,很容易产生 “段错误”。
复制代码

   4.链接线程(阻塞)

int pthread_join(pthread_t thread, void **value_ptr);
  
  等待线程thread结束,并设置*value_ptr为thread的返回值。pthread_join阻塞调用者,一直到线程thread结束为止。当函数返回时,被等待线程的资源被收回。若是进程已经结束,那么该函数会当即返回。而且thread指定的线程必须是joinable的。

须要留意的一点是linux机制下,线程存在一个被称为joinable的状态。下面简要了解一下:
复制代码

Join和Detach 这块的概念,很是相似于以前父子进程那部分,等待子进程退出的内容(一系列的wait函数)。

linux机制下,线程存在两种不一样的状态:joinable和unjoinable。

若是一个线程被标记为joinable时,即使它的线程函数执行完了,或者使用了pthread_exit()结束了该线程,它所占用的堆栈资源和进程描述符都不会被释放(相似僵尸进程),这种状况应该由线程的建立者调用pthread_join()来等待线程的结束并回收其资源(相似wait系函数)。默认状况下建立的线程都是这种状态。

若是一个线程被标记成unjoinable,称它被分离(detach)了,这时候若是该线程结束,全部它的资源都会被自动回收。省去了给它擦屁股的麻烦。

由于建立的线程默认都是joinable的,因此要么在父线程调用pthread_detach(thread_id)将其分离,要么在线程内部,调用pthread_detach(pthread_self())来把本身标记成分离的。
复制代码

文件系统

文件描述符在linux内核中,文件是用一个整数来表示的,称为 文件描述符,通俗的来讲,你能够理解它是文件的id(惟一标识符)

普通文件
普通文件就是字节流组织的数据。
文件并非经过和文件名关联来实现的,而是经过关联索引节点来实现的,文件节点拥有文件系统为普通文件分配的惟一整数值(ino),而且存放着一些文件的相关元数据。

目录与连接
正常状况下文件是经过文件名来打开的。
目录是可读名称到索引编号之间的映射,名称和索引节点之间的配对称为连接。
能够把目录看作普通文件,只是它包含着文件名称到索引节点的映射(连接)
复制代码

文件系统是基于底层存储创建的一个树形文件结构。比较经典的是Linux的文件系统,首先在硬盘的超级块中安装文件系统,磁盘引导时会加载文件系统的信息。

linux使用inode来标识任意一个文件。inode存储除了文件名之外的文件信息,包括建立时间,权限,以及一个指向磁盘存储位置的指针,那里才是真正存放数据的地方。

一个目录也是一个inode节点。

详细阐述一次文件访问的过程:

首先用户ls查看目录。因为一个目录也是一个文件,因此至关因而看目录文件下有哪些东西。

实际上目录文件是一个特殊的inode节点,它不须要存储实际数据,而只是维护一个文件名到inode的映射表。

因而咱们ls到另外一个目录。同理他也是一个inode。咱们在这个inode下执行vi操做打开某个文件,因而linux经过inode中的映射表找到了咱们请求访问的文件名对应的inode。

而后寻道到对应的磁盘位置,读取内容到缓冲区,经过系统调用把内容读到内存中,最后进行访问。
复制代码

IO操做

文件描述符

  对于内核而言,全部打开的文件都经过文件描述符引用。文件描述符是一个非负整数。当打开一个现有文件或建立一个新文件时,内核向进程返回一个文件描述符。当读或写一个文件时,使用open或create返回的文件描述符表示该文件,将其做为参数传给read或write函数。

write函数

  write函数定义以下:

#include  ssize_t write(int filedes, void *buf, size_t nbytes); // 返回:若成功则返回写入的字节数,若出错则返回-1 // filedes:文件描述符 // buf:待写入数据缓存区 // nbytes:要写入的字节数

  一样,为了保证写入数据的完整性,在《UNIX网络编程 卷1》中,做者将该函数进行了封装,具体程序以下:

复制代码

 1 ssize_t                        /* Write "n" bytes to a descriptor. */
 2 writen(int fd, const void *vptr, size_t n)
 3 {
 4     size_t nleft;
 5     ssize_t nwritten;
 6     const char *ptr;
 7 
 8     ptr = vptr; 9     nleft = n; 10     while (nleft > 0) { 11         if ( (nwritten = write(fd, ptr, nleft)) <= 0) { 12             if (nwritten < 0 && errno == EINTR) 13                 nwritten = 0;        /* and call write() again */
14             else
15                 return(-1);            /* error */
16 } 17 
18         nleft -= nwritten; 19         ptr   += nwritten; 20 } 21     return(n); 22 } 23 /* end writen */
24 
25 void
26 Writen(int fd, void *ptr, size_t nbytes) 27 { 28     if (writen(fd, ptr, nbytes) != nbytes) 29         err_sys("writen error"); 30 }

复制代码

read函数

  read函数定义以下:

#include  ssize_t read(int filedes, void *buf, size_t nbytes); // 返回:若成功则返回读到的字节数,若已到文件末尾则返回0,若出错则返回-1 // filedes:文件描述符 // buf:读取数据缓存区 // nbytes:要读取的字节数

  有几种状况可以使实际读到的字节数少于要求读的字节数:

  1)读普通文件时,在读到要求字节数以前就已经达到了文件末端。例如,若在到达文件末端以前还有30个字节,而要求读100个字节,则read返回30,下一次再调用read时,它将返回0(文件末端)。

  2)当从终端设备读时,一般一次最多读一行。

  3)当从网络读时,网络中的缓存机构可能形成返回值小于所要求读的字结束。

  4)当从管道或FIFO读时,如若管道包含的字节少于所需的数量,那么read将只返回实际可用的字节数。

  5)当从某些面向记录的设备(例如磁带)读时,一次最多返回一个记录。

  6)当某一个信号形成中断,而已经读取了部分数据。

  在《UNIX网络编程 卷1》中,做者将该函数进行了封装,以确保数据读取的完整,具体程序以下:

复制代码

 1 ssize_t                        /* Read "n" bytes from a descriptor. */
 2 readn(int fd, void *vptr, size_t n)
 3 {
 4     size_t nleft;
 5     ssize_t nread;
 6     char *ptr;
 7 
 8     ptr = vptr; 9     nleft = n; 10     while (nleft > 0) { 11         if ( (nread = read(fd, ptr, nleft)) < 0) { 12             if (errno == EINTR) 13                 nread = 0;        /* and call read() again */
14             else
15                 return(-1); 16         } else if (nread == 0) 17             break;                /* EOF */
18 
19         nleft -= nread; 20         ptr   += nread; 21 } 22     return(n - nleft);        /* return >= 0 */
23 } 24 /* end readn */
25 
26 ssize_t 27 Readn(int fd, void *ptr, size_t nbytes) 28 { 29 ssize_t        n; 30 
31     if ( (n = readn(fd, ptr, nbytes)) < 0) 32         err_sys("readn error"); 33     return(n); 34 }

复制代码

本文下半部分摘自博文浅谈TCP/IP网络编程中socket的行为

read/write的语义:为何会阻塞?

  先从write提及:

#include  ssize_t write(int fd, const void *buf, size_t count);

  首先,write成功返回,**只是buf中的数据被复制到了kernel中的TCP发送缓冲区。**至于数据何时被发往网络,何时被对方主机接收,何时被对方进程读取,系统调用层面不会给予任何保证和通知。

  write在什么状况下会阻塞?当kernel的该socket的发送缓冲区已满时。对于每一个socket,拥有本身的send buffer和receive buffer。从Linux 2.6开始,两个缓冲区大小都由系统来自动调节(autotuning),但通常在default和max之间浮动。

# 获取socket的发送/接受缓冲区的大小:(后面的值是在Linux 2.6.38 x86_64上测试的结果)
sysctl net.core.wmem_default       #126976
sysctl net.core.wmem_max        #131071

  已经发送到网络的数据依然须要暂存在send buffer中,只有收到对方的ack后,kernel才从buffer中清除这一部分数据,为后续发送数据腾出空间。接收端将收到的数据暂存在receive buffer中,自动进行确认。但若是socket所在的进程不及时将数据从receive buffer中取出,最终致使receive buffer填满,因为TCP的滑动窗口和拥塞控制,接收端会阻止发送端向其发送数据。这些控制皆发生在TCP/IP栈中,对应用程序是透明的,应用程序继续发送数据,最终致使send buffer填满,write调用阻塞。

  通常来讲,因为接收端进程从socket读数据的速度跟不上发送端进程向socket写数据的速度,最终致使发送端write调用阻塞。

  而read调用的行为相对容易理解,从socket的receive buffer中拷贝数据到应用程序的buffer中。read调用阻塞,一般是发送端的数据没有到达。

Linux经常使用命令和基础知识

查看进程

1. ps
查看某个时间点的进程信息

示例一:查看本身的进程

# ps -l
示例二:查看系统全部进程

# ps aux
示例三:查看特定的进程

# ps aux | grep threadx

2. top
实时显示进程信息

示例:两秒钟刷新一次

# top -d 2
3. pstree
查看进程树

示例:查看全部进程树

# pstree -A
4. netstat
查看占用端口的进程

示例:查看特定端口的进程

# netstat -anp | grep port
复制代码

文件操做

ls -a ,all列出所有文件包括隐藏

ls -l,list显示文件的所有属性

ls -d,仅列出目录自己

cd mkdir rmdir 经常使用不解释 rm -rf永久删除 cp复制 mv移动或更名

touch,更新文件时间或者创建新文件。

权限操做

chmod rwx 分别对应 421

 chmod 754 .bashrc 将权限改成rwxr-xr--

对应权限分配是对于 拥有者,所属群组,以及其余人。
复制代码

文件默认权限

文件默认权限:文件默认没有可执行权限,所以为 666,也就是 -rw-rw-rw- 。

目录默认权限:目录必需要可以进入,也就是必须拥有可执行权限,所以为 777 ,也就是 drwxrwxrwx。

目录的权限

ps:拥有目录权限才能修改文件名,拥有文件权限是没用的

文件名不是存储在一个文件的内容中,而是存储在一个文件所在的目录中。所以,拥有文件的 w 权限并不能对文件名进行修改。
复制代码

目录存储文件列表,一个目录的权限也就是对其文件列表的权限。所以,目录的 r 权限表示能够读取文件列表;w 权限表示能够修改文件列表,具体来讲,就是添加删除文件,对文件名进行修改;x 权限可让该目录成为工做目录,x 权限是 r 和 w 权限的基础,若是不能使一个目录成为工做目录,也就没办法读取文件列表以及对文件列表进行修改了。

链接操做

硬连接:

使用ln创建了一个硬链接,经过ll -i得到他们的inode节点。发现他们的inode节点是相同的。符合硬链接规定。


# 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 读取内容 加上-n 按行打印

tac是cat的反向操做

more容许翻页查看,而不像cat一次显示所有内容

less能够先前翻页和向后翻页,more只能向前翻页

head 和tail 负责取得文件的前几行和后几行

搜索和定位

1 which负责指令搜索,并显示第一条 好比which pwd,会找到pwd对应的程序。加-a 打印所有。

2 whereis负责搜索文件, 后面接上dirname/filename

文件搜索。速度比较快,由于它只搜索几个特定的目录。
好比 whereis /bin hello.c

3 locate
文件搜索。能够用关键字或者正则表达式进行搜索。

locate 使用 /var/lib/mlocate/ 这个数据库来进行搜索,它存储在内存中,而且天天更新一次,因此没法用 locate 搜索新建的文件。可使用 updatedb 来当即更新数据库。

# locate [-ir] keyword
-r:正则表达式

locate hello 
locate he*
vi heeee
updatedb
locate he?

4. find
文件搜索。可使用文件的属性和权限进行搜索。

# find [basedir] [option]
example: find . -name "shadow*"

find -name "hike"
find +属性后缀 "属性"

(一)与时间有关的选项

-mtime  n :列出在 n 天前的那一天修改过内容的文件

(二)与文件拥有者和所属群组有关的选项

-uid n
-gid n
-user name

(三)与文件权限和名称有关的选项

-name filename
-size [+-]SIZE:搜寻比 SIZE 还要大 (+) 或小 (-) 的文件。这个 SIZE 的规格有:c: 表明 byte,k: 表明 1024bytes。因此,要找比 50KB 还要大的文件,就是 -size +50k
-type TYPE
复制代码

压缩

gzip压缩和解压,还有bzip,xz等压缩

而tar能够用打包,打包的时候也能够执行压缩

压缩指令只能对一个文件进行压缩,而打包可以将多个文件打包成一个大文件。tar 不只能够用于打包,也可使用 gip、bzip二、xz 将打包文件进行压缩。

$ tar [-z|-j|-J] [cv] [-f 新建的 tar 文件] filename...  ==打包压缩
$ tar [-z|-j|-J] [tv] [-f 已有的 tar 文件]              ==查看
$ tar [-z|-j|-J] [xv] [-f 已有的 tar 文件] [-C 目录]    ==解压缩
复制代码

管道指令

1 |

2 cut切分数据,分红多列,last显示登录者信息

正则

grep

g/re/p(globally search a regular expression and print),使用正则表示式进行全局查找并打印。

$ grep [-acinv] [--color=auto] 搜寻字符串 filename
-c : 计算找到个数
-i : 忽略大小写
-n : 输出行号
-v : 反向选择,亦即显示出没有 搜寻字符串 内容的那一行
--color=auto :找到的关键字加颜色显示
复制代码

awk

$ awk '条件类型 1 {动做 1} 条件类型 2 {动做 2} ...' filename
示例 2:/etc/passwd 文件第三个字段为 UID,对 UID 小于 10 的数据进行处理。

$ cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}'
root 0
bin 1
daemon 2
sed

示例 3:输出正在处理的行号,并显示每一行有多少字段

$ last -n 5 | awk '{print $1 "\t lines: " NR "\t columns: " NF}'
dmtsai lines: 1 columns: 10
dmtsai lines: 2 columns: 10
dmtsai lines: 3 columns: 10
dmtsai lines: 4 columns: 10
dmtsai lines: 5 columns: 9
复制代码

sed:

awk用于匹配每一行中的内容并打印
而sed负责把文件内容重定向到输出,因此sed读取完文件并重定向到输出而且经过awk匹配这些内容并打印。

他们俩常常搭配使用。
复制代码

linux指令实践和常见场景

查看进程状态

Linux进程状态(ps stat)之R、S、D、T、Z、X

D    不可中断     Uninterruptible sleep (usually IO)
R    正在运行,或在队列中的进程
S    处于休眠状态
T    中止或被追踪
Z    僵尸进程
W    进入内存交换(从内核2.6开始无效)
X    死掉的进程


<    高优先级
N    低优先级
L    有些页被锁进内存
s    包含子进程
+    位于后台的进程组;
l    多线程,克隆线程  multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
复制代码

ps aux

strace

strace用于跟踪程序执行过程当中的系统调用,如跟踪test进程,只须要:

strace -p [test_pid] 或直接strace ./test

好比,跟踪pid为12345的进程中全部线程的read和write系统调用,输出字符串的长度限制为1024:

strace -s 1024 -f -e trace=read,write -p 12345

tcpdump

tcpdump是Linux上的抓包工具,如抓取eth0网卡上的包,使用:

sudo tcpdump -i eth0

好比,抓取80端口的HTTP报文,以文本形式展现:

sudo tcpdump -i any port 80 -A 这样你就能够清楚看到GET、POST请求的内容了。

nc

nc能够在Linux上开启TCP Server、TCP Client、UDP Server、UDP Client。

如在端口号12345上开启TCP Server和Client模拟TCP通讯:

Server: nc -l 127.0.0.1 12345 Client: nc 127.0.0.1 12345 在端口号12345上开启UDP Server和Client模拟TCP通讯:

Server: nc -ul 127.0.0.1 12345 Client: nc -u 127.0.0.1 12345 Unix Socket通讯示例:

Server: nc -Ul /tmp/1.sock Client: nc -U /tmp/1.sock

curl

curl用于模拟HTTP请求,在终端模拟请求时经常使用,如最基本的用法:

curl http://www.baidu.com

lsof

lsof命令主要用法包括:

sudo lsof -i :[port] 查看端口占用进程信息,常常用于端口绑定失败时确认端口被哪一个进程占用

sudo lsof -p [pid] 查看进程打开了哪些文件或套接字

ss

Linux上的ss命令能够用于替换netstat,ss直接读取解析/proc/net下的统计信息,相比netstat遍历/proc下的每一个PID目录,速度快不少。

awk/sed

awk和sed在文本处理方面十分强大,其中,awk按列进行处理,sed按行进行处理。

如采用冒号分隔数据,输出第一列数据($0表明行所有列数据,$1表明第一列,$2表明第二列...)

awk -F ":" '{print $1}' 在awk的结果基础上,结合sort、uniq和head等命令能够轻松完成频率统计等功能

查看文件的第100行到第200行: sed -n '100,200p' log.txt 替换字符串中的特定子串 echo "int charset=gb2312 float"|sed "s/charset=gb2312/charset=UTF-8/g" 替换test文件每行匹配ab的部分为cd sed -i 's/ab/cd/g' test

vim

打开文件并跳到第10行

$ vim +10 filename.txt 打开文件跳到第一个匹配的行

$ vim +/search-term filename.txt 以只读模式打开文件

$ vim -R /etc/passwd

crontab

查看某个用户的crontab入口

$ crontab -u john -l 设置一个每十分钟执行一次的计划任务

*/10 * * * * /home/ramesh/check-disk-space 更多示例:Linux Crontab: 15 Awesome Cron Job Examples

service

service命令用于运行System V init脚本,这些脚本通常位于/etc/init.d文件下,这个命令能够直接运行这个文件夹里面的脚本,而不用加上路径

查看服务状态

$ service ssh status 查看全部服务状态

$ service --status-all 重启服务

$ service ssh restart

free

这个命令用于显示系统当前内存的使用状况,包括已用内存、可用内存和交换内存的状况

默认状况下free会以字节为单位输出内存的使用量

$ free
             total       used       free     shared    buffers     cached
Mem:       3566408    1580220    1986188          0     203988     902960
-/+ buffers/cache:     473272    3093136
Swap:      4000176          0    4000176
复制代码

若是你想以其余单位输出内存的使用量,须要加一个选项,-g为GB,-m为MB,-k为KB,-b为字节

$ free -g
             total       used       free     shared    buffers     cached
Mem:             3          1          1          0          0          0
-/+ buffers/cache:          0          2
Swap:            3          0          3
复制代码

若是你想查看全部内存的汇总,请使用-t选项,使用这个选项会在输出中加一个汇总行

ramesh@ramesh-laptop:~$ free -t
             total       used       free     shared    buffers     cached
Mem:       3566408    1592148    1974260          0     204260     912556
-/+ buffers/cache:     475332    3091076
Swap:      4000176          0    4000176
Total:     7566584    1592148    5974436
复制代码

top

top命令会显示当前系统中占用资源最多的一些进程(默认以CPU占用率排序)若是你想改变排序方式,能够在结果列表中点击O(大写字母O)会显示全部可用于排序的列,这个时候你就能够选择你想排序的列

Current Sort Field:  P  for window 1:Def
Select sort field via field letter, type any other key to return

  a: PID        = Process Id              v: nDRT       = Dirty Pages count
  d: UID        = User Id                 y: WCHAN      = Sleeping in Function
  e: USER       = User Name               z: Flags      = Task Flags
  ........
复制代码

若是只想显示某个特定用户的进程,可使用-u选项

$ top -u oracle

df

显示文件系统的磁盘使用状况,默认状况下df -k 将以字节为单位输出磁盘的使用量

$ df -k

Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda1             29530400   3233104  24797232  12% /
/dev/sda2            120367992  50171596  64082060  44% /home
复制代码

使用-h选项能够以更符合阅读习惯的方式显示磁盘使用量

$ df -h

Filesystem                  Size   Used  Avail Capacity  iused      ifree %iused  Mounted on
/dev/disk0s2               232Gi   84Gi  148Gi    37% 21998562   38864868   36%   /
devfs                      187Ki  187Ki    0Bi   100%      648          0  100%   /dev
map -hosts                   0Bi    0Bi    0Bi   100%        0          0  100%   /net
map auto_home                0Bi    0Bi    0Bi   100%        0          0  100%   /home
/dev/disk0s4               466Gi   45Gi  421Gi    10%   112774  440997174    0%   /Volumes/BOOTCAMP
//app@izenesoft.cn/public  2.7Ti  1.3Ti  1.4Ti    48% 
复制代码

kill

kill用于终止一个进程。通常咱们会先用ps -ef查找某个进程获得它的进程号,而后再使用kill -9 进程号终止该进程。你还可使用killall、pkill、xkill来终止进程

$ ps -ef | grep vim ramesh 7243 7222 9 22:43 pts/2 00:00:00 vim

$ kill -9 7243

mount

若是要挂载一个文件系统,须要先建立一个目录,而后将这个文件系统挂载到这个目录上

mkdir /u01 mount /dev/sdb1 /u01 也能够把它添加到fstab中进行自动挂载,这样任什么时候候系统重启的时候,文件系统都会被加载

/dev/sdb1 /u01 ext2 defaults 0 2

chmod

chmod用于改变文件和目录的权限

给指定文件的属主和属组全部权限(包括读、写、执行)

$ chmod ug+rwx file.txt 删除指定文件的属组的全部权限

$ chmod g-rwx file.txt 修改目录的权限,以及递归修改目录下面全部文件和子目录的权限

$ chmod -R ug+rwx file.txt 更多示例:7 Chmod Command Examples for Beginners

chown

chown用于改变文件属主和属组

同时将某个文件的属主改成oracle,属组改成db

$ chown oracle:dba dbora.sh 使用-R选项对目录和目录下的文件进行递归修改

$ chown -R oracle:dba /home/oracle

ifconfig

ifconfig用于查看和配置Linux系统的网络接口

uname

uname能够显示一些重要的系统信息,例如内核名称、主机名、内核版本号、处理器类型之类的信息

实际场景问题

1 cpu占用率

top能够看
ps看不了
可是ps -aux能够看到各个线程的cpu和内存占用

2 进程状态:

ps -ef看不了
ps aux能够看进程状态S R之类

3 IO
iostat查看io状态

4网络
netstat查看tcp链接状态和socket状况,

ipconfig查看网络设备

lsof能够查看端口使用状况

5内存
free复制代码
相关文章
相关标签/搜索