Linux常用shell语法和命令

If else

Shell共有三种三种if…else分支

  • if…fi语句
  • if…else…fi语句
  • if…elif…else…fi语句

1、if…else语句

if [ expression ]
    then
Statement(s) to be executed if expression is true
fi

注意:expression 和方括号([ ])之间必须有空格,否则会有语法错误。

if…else也可以写成一行,以命令的方式来运行,像这样:

if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;

2、if条件表达式中的额外判断

字符串的判断

  • str1 = str2 两个字符串有相同内容、长度时为真
  • str1 != str2
  • -n str1 字符串的长度大于0返回真
  • -z str1 字符串的长度等于0时返回真
  • str1 字符串为非空返回真

比较两个字符串是否相等的时候,一般的做法是:

if [ "$test"x = "test"x ]; then 

主要考虑以下几点

  • 使用单个等号
  • 注意到等号两边各有一个空格:这是unix shell的要求
  • 注意到”test"x最后的x,这是特意安排的,因为当test"x最后的x,这是特意安排的,因为当test为空的时候,上面的表达式就变成了x = testx,显然是不相等的。而如果没有这个x,表达式就会报错:[: =: unary operator expected

数字的判断

  • int1 -eq int2 两数相等返回真
  • int1 -ne int2 两数不相等返回真
  • int1 -gt int2 int1大于int2为真
  • int1 -ge int2 int1大于等于int2为真
  • int1 -lt int2 int1小于int2为真
  • int1 -le int2 int1小于等于int2为真

复杂逻辑判断

  • -a 与
  • -o 或
  • ! 非

文件的判断

  • -e filename 如果 filename存在,则为真
  • -d filename 如果 filename为目录,则为真
  • -f filename 如果 filename为常规文件,则为真
  • -L filename 如果 filename为符号链接,则为真
  • -r filename 如果 filename可读,则为真
  • -w filename 如果 filename可写,则为真
  • -x filename 如果 filename可执行,则为真
  • -s filename 如果文件长度不为0,则为真

判断/home/oicq/script/get_random_shm_key.sh是否存在

if [ -e /home/oicq/script/get_random_shm_key.sh ]

判断文件大小是否为空

if [ ! -s ${REMOTE_FILE} ]
    then
        SH_error_msg "${REMOTE_FILE} file is empty"
        return 1
    fi

循环

For

for循环的一般格式为:

for 变量 in 列表
do
    command1
    command2
    ...
    commandN
done

列表 是一组值(数字,字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个赋给变量。

in 列表是可选的,如果不用它,for 循环使用命令行的位置参数

  • 顺序输出当前列表中的数字
for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done

运行结果如下:

The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
  • 1到100输出
for i in {1..100}  
do  
    echo $i  
done  
  • 显示主目录下以.bash开头的文件
#!/bin/bash
for FILE in $HOME/.bash*
do
   echo $FILE
done

运行结果如下:

/root/.bash_history
/root/.bash_logout
/root/.bash_profile
/root/.bashrc

while

while循环的一般格式为:

while 条件语句

do

action

done;

示例:从文件中读取内容

while read line;do
    echo $line;
done < /etc/hosts;

替换

1、命令替换

命令替换$(cmd)以及`cmd`

$ ls 
a b c 
$ echo $(ls) 
a b c 
$ echo `ls` 
a b c

对于echo $(ls),shell执行时会先执行$(ls),得到其标准输出,在用得到输出替换原来位置上的$(ls),再执行echo命令。

注意:$(cmd)中的命令的错误输出是不会被替换的,只有标准输出

$ var=$(cat d)
cat: d

这里由于文件d在当前目录不存在

2、一串命令的执行()和{}

(){}都是对一串的命令进行执行,但是有所区别:

  • ()只是对一串命令重新开一个子shell进行执行
  • {}对一串命令在当前shell执行
  • (){}都是把一串的命令放在括号里面,并且命令之间用;号隔开
  • ()最后一个命令可以不用分号
  • {}最后一个命令要用分号
  • {}的第一个命令和左括号之间必须要有一个空格
  • ()里的各命令不必和括号有空格
  • (){}中括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的所有命令
$ var=test 
$ (var=notest; echo $var) ###变量var值为notest,此是在子shell中有效 
notest 
$ echo $var ###父shell中值仍为test 
test 
$ { var=notest; echo $var;} ###注意左括号和var之间要有一个空格 
notest 
$ echo $var ###父shell中的var变量的值变为了notest 
notest 
$ { var1=test1;var2=test2;echo $var1>a;echo $var2;} ###输出test1被重定向到文件a中, 
test2 ###而test2输出则仍输出到标准输出中。 
$ cat a 
test1 
$ { var1=test1;var2=test2;echo $var1;echo $var2;}>a ###括号内命令的标准输出全部被重定向到文件a中
$ cat a 
test1 
test2

变量

1、shell中0,0,1等变量

  • $$:shell本身的PID
  • $?:shell最后运行的命令的结束代码
  • $*:所有参数列表,如果使用”“括起来的话,会以”11 2 …$n”形式输出
  • $@:所有参数列表,如果使用”“括起来的话,会以”1”“1” “2” … “$n”形式输出**
  • $#:添加到shell的参数个数
  • $0:shell本身文件名
  • 1 1~n:添加到shell的各个参数值

∗和*和@在不加引号的时候,都可以表示一个参数数组;而在加了引号之后,”∗"就表示一个参数字符串,而"*"就表示一个参数字符串,而"@”依然表示一个参数数组

${var%pattern},表示从变量$var的结尾删除最短匹配pattern的子串

${0%/*}表示删除从变量0尾部开始第一个‘/‘之后匹配的内容,比如0尾部开始第一个`/`之后匹配的内容,比如0是这个目录/home/john/source 那么就是把”/source”截取掉,剩下/home/john,一般用来获取当前执行脚本的目录

2、脚本变量和函数变量

  • shell中脚本定义的变量是global的,其作用域是从被定义的地方开始的,到shell结束或是被显示删除的地方为止。
#!/bin/bash
#define the function ltx_func
ltx_func()
{
   echo $v1
   #modify the variable v1
   v1=200 
}
#define the variable v1
v1=100
#call the function ltx_func
ltx_func
echo $v1

运行结果如下:

100
200

脚本变量v1的作用域从被定义的地方开始,到shell结束。调用ltx_func在变量v1的作用域内,所以能够访问并修改v1

  • 函数定义的local变量
#!/bin/bash
#define the function ltx_func
ltx_func()
{
   #define the local variable v2
   local v2=200 
}
#call the function ltx_func
ltx_func
echo $v2

运行结果如下:

(空)

函数变量v2显示定义为local,其作用域局限于函数内。打印命令在函数外,不在变量v2的作用域内。

  • 函数参数是local变量
#!/bin/bash
#define the function ltx_func
ltx_func()
{
   echo "param 1: $1"
}
#call the function ltx_func
ltx_func 100

运行结果如下:

100

函数参数是local的,通过位置变量$1来访问

  • 如果同名,shell函数定义的local变量会屏蔽脚本定义的global变量
#!/bin/bash
#define the function ltx_func
ltx_func()
{
   echo $v1
   #define the local variable v1
   local v1=200 
   echo $v1
}
#define the global variable v1
v1=100 
#call the function ltx_func
ltx_func
echo $v1

运行结果如下:

100
200
100

global变量v1的作用域从被定义的地方开始,到shell结束。在函数内又定义了local变量v1,同名local变量v1会覆盖globa变量v1。退出函数后,函数内定义的local变量v1已经消失,访问的是global变量。

算数运算

expr

expr命令是一款表达式计算工具,使用它完成表达式的求值操作。

expr常用运算符:

  • 加法运算:+
  • 减法运算:-
  • 乘法运算:\*
  • 除法运算:/
  • 求摸(取余)运算:%

示例:

$expr 9 + 8 - 7 \* 6 / 5 + \( 4 - 3 \) \* 2
11

expr同时还可以对字符串进行操作: - match 字符串 表达式等于”字符串 :表达式” - substr 字符串 偏移量 长度替换字符串的子串,偏移的数值从 1 起计 - index 字符串 字符在字符串中发现字符的地方建立下标,或者标0 - length 字符串字符串的长度

bc

上面我们介绍的expr之支持整数运算,但对于浮点运算就无能为力了,而且expr不能进行指数运算,而都有bc这些都不再话下。

参数:

  • -i 强制交互模式;
  • -l 使用bc的内置库,bc里有一些数学库,对三角计算等非常实用;
  • -q 进入bc交互模式时不再输出版本等多余的信息。

特殊变量:

ibase,obase 用于进制转换,ibase是输入的进制,obase是输出的进制,默认是十进制;

scale 小数保留位数,默认保留0位。

交互模式:在shell命令行直接输入bc及能进入bc语言的交互模式。 非交互模式:与echo方法一起使用。

$echo "scale=5;9+8-7*6/5^2"|bc
15.32000

$echo "ibase=16;obase=2;ABC"|bc
101010111100

小技巧:可以使用gdb来进行10进制转成16进制,print /x [num]

(( )) 和 [ ]

这两个在shell中比较常见,这两个和expr命令有些类似,也是用于整数计算。

这两个对与expr的优点是:运算符号全部不需要转义

$echo $(( 2 + 5 ))
7

$echo $(( 2 * 5 ))
10

$echo $[ 2 % 5 ]
2

$echo $[ 2 * 5 ]
10

执行多个命令

使用;

连续不中断执行命令,中间出现错误并不会中断后面命令,例如:

mkdir test; mkdir test; rmdir test;

虽然第二个命令会出错,但不会影响后面的删除目录命令

使用&&

使用&&分割的命令,如果没有错误会一直执行下去,出现错误会立即中止,例如:

mkdir test && mkdir test && rmdir test

这里在第二个命令处就终止了

使用||

使用||分隔的命令,如果有错误就一直执行下去,直到一次正确的执行就立即终止,例如:

mkdir test || mkdir test || rmdir test
mkdir test || mkdir test || rmdir test || mkdir test

第一次执行第一条指令就正确,后面的不执行

第二次执行前两条都错误,直到最后一条才正确,最后一条不再执行

多个命令构成一个数组,然后批量执行

1、(命令1;命令2;命令3)

其中()会开启一个子Shell环境来执行括号中的命令

2、{ 命令1;命令2;命令3 }

这里要注意的就是{的右边必须要有一个空格,}的左边也需要有一个空格 。和上面的方法不同的是,该方法是把批命令放在现行的shell中执行,而不是子shell中执行。

grep

基本命令

grep在一个或多个文件中查找与模式字符串(pattern)匹配的行,并将搜索的结果打印出来,不会修改原文件内容。 使用grep 命令的语法为: grep [option] pattern [file(s)]

常用选项

  • -a 不要忽略二进制数据。
  • -c 计算符合范本样式的列数。
  • -n 在显示符合范本样式的那一列之前,标示出该列的编号。
  • -v 反转查找。

-A-B-选项详解

-A可以理解为显示查找到的行之后,还会显示之后的一行或是多行(after)

-B可以理解为显示查找到的行之后,还会显示之前的一行或是多行(before)

显示之后一行:
grep -A1 keyword filename

显示之前一行:
grep -B1 keyword filename

显示之前和之后一行
grep -1 keyword filename

正则表达式

使用[]搜索集合字符

[chainyang@DSNO_DP_PD_2 ~/small_program]$ grep '[ae]st' test.txt --color=auto
past
test
best

可以用^符号做[]内的前缀,表示除[]内的字符之外的字符。

而如果^符号不再[]内,那么就可以用来表示开头,$表示结尾。

搜索以小写字母开头的行

grep -n '^[a-z]' regular_express.txt 

搜索开头不是英文字母的行

grep -n '^[^a-zA-Z]' regular_express.txt 

Sort

sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。sort命令既可以从特定的文件,也可以从stdin中获取输入。

基本命令

sort(选项)(参数)

选项

  • -s: sort命令默认是不稳定的排序,此选项使排序结果稳定;
  • -b:忽略每行前面开始出的空格字符;
  • -c:检查文件是否已经按照顺序排序;
  • -d:排序时,处理英文字母、数字及空格字符外,忽略其他的字符;
  • -f:排序时,将小写字母视为大写字母;
  • -i:排序时,除了040至176之间的ASCII字符外,忽略其他的字符;
  • -m:将几个排序号的文件进行合并;
  • -M:将前面3个字母依照月份的缩写进行排序;
  • -n:依照数值的大小排序;
  • -o<输出文件>:将排序后的结果存入制定的文件;
  • -r:以相反的顺序来排序;
  • -t<分隔字符>:指定排序时所用的栏位分隔字符;
  • +<起始栏位>-<结束栏位>:以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。
  • -k:

实例

sort将文件/文本的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。

[root@mail text]# cat sort.txt 
AAA:BB:CC 
aaa:30:1.6 
ccc:50:3.3 
ddd:20:4.2 
bbb:10:2.5 
eee:40:5.4 
eee:60:5.1

# 第二列按照数字从小到大顺序排列:
[root@mail text]# sort -nk 2 -t: sort.txt 
AAA:BB:CC 
bbb:10:2.5 
ddd:20:4.2 
aaa:30:1.6 
eee:40:5.4 
ccc:50:3.3 
eee:60:5.1

# 将CC列数字从大到小顺序排列: 
[root@mail text]# sort -nrk 3 -t: sort.txt
eee:40:5.4 
eee:60:5.1 
ddd:20:4.2 
ccc:50:3.3 
bbb:10:2.5 
aaa:30:1.6 
AAA:BB:CC

上述示例中-n按照数字大小排序,-r是以相反的顺序排序,-k指定需要排序的栏位,-t指定栏位分隔符为冒号。

-k语法使用

FStart.CStart Modifie,FEnd.CEnd Modifier

——-Start——–,——-End——–

FStart.CStart 选项 , FEnd.CEnd 选项

逗号 左边的是Start部分,逗号 右边的End部分。

Start部分包括三部分构成,这里的Modifie就是前面提到的-n-r选项,而FStart.CStart表示的就是从第几栏中的第几个字符开始,如果省略.CStart表示从本栏的开头部分开始。

End部分同理,如果省略.CEnd,表示结尾到本栏尾

# 使用 -k 1.2 表示对第一栏中的第二个字符开始到本栏最后一个字符为止的字串进行排序
$ sort -t ' ' -k 1.2 facebook.txt 
baidu 100 5000 
sohu 100 4500 
google 110 5000 
guge 50 3000

# 只针对公司英文名称的第二个字母进行排序,如果相同的按照员工工资进行排序
# -k 1.2,1.2表示只对第二个字母进行排序,-nrk 3,3表示对员工工资进行排序

$ sort -t ' ' -k 1.2,1.2 -nrk 3,3 
facebook.txt baidu 100 5000 
google 110 5000 
sohu 100 4500 
guge 50 3000

Sed

基本命令

sed的一般命令格式如下:

sed [options] [commands] filename

更详细的命令格式如下:

sed [OPTION]... '抓取条件/编辑命令' [input-file]...

sed的四个要素就是选项抓取条件处理动作以及被处理文件

基本原理

sed以行为处理单位(即将缓存一行到patter space),默认输入输出均为系统标准输入输出(因此除非重定向,否则它并不真正修改文件),它首先判断要处理的行是否在要处理的范围之内(通过抓取条件,即SELECTION),如果是则读入pattern space中,这是sed进行字符串处理工作的一个区域。脚本中的sed命令逐条执行来编辑pattern space里面的字符串,执行完毕后将该pattern space中处理过的字符串进行输出,随之pattern space被清空;接着,再重复执行刚才的动作,文件中的新的一行被读入,判断是否在SELECTION中,编辑、输出,直到文件 处理完毕,整个过程如下图所示。

除了 pattern space 外,sed还有一个 hold space,用处是暂存文字字符串的地方,hold space中的字符串只是用于临时处理的中间结果,是不会被输出的。

常用选项

  • -n:禁用默认输出。默认情况下,sed会将输入的内容每行都打印,使用-n就可以禁用默认输出,仅仅输出缓冲区的行
  • -f:直接将sed的动作写入到一个文件中,-f filename则可以执行filename内的sed的动作
  • -e:使用多个sed指令,如果有多个sed指令需要执行,例如:sed -e ‘cmd1’ -e ‘cmd2’ … -e ‘cmdN’ file
  • -i:直接修改源文件。默认处理动作发生在内存空间,不会影响源文件

抓取条件(SELECTION)

sed不会对文件中的每一行做action,只会把符合条件的行送入模式空间来进行处理。

抓取条件通常有地址定界以及正则寻址两种配合使用。

1、地址定界

  • 单个行号:如1为取第一行,5为取第五行,$为取最后一行
  • 范围行:如1,3表示闭区间从第一行到第三行,如1~2~表示的步长,即第一行,第三行,第五行

2、正则寻址

  • 单个正则匹配:如/string/为抓取包含string的行
  • 一个正则匹配范围:如/^on/,/off$/为抓取从on开头到off结尾的行之间(包含这两个匹配行)的文本
  • 行范围与正则匹配范围集合:如10,/string/表示从第10行到第一次匹配到string的行之间的文本
  • 除去所匹配行外的范围:如/Llew/! 表示除了匹配Llew的行外其余的文本行

处理动作

1、追加

命令 sed 'SELECTION a\ [text]' file(s),例如sed ‘a 2 \hello’就表示在第二行后追加一行hello

2、插入

命令 sed 'SELECTION i\ [text]' file(s),插入一行,原来行后推

3、更改

命令 sed 'SELECTION c\ [text]' file(s),修改当前行的内容

4、删除

命令 sed 'SELECTION d' file(s),修改当前行的内容

5、替换内容

使用s命令

基本格式:sed 'SELECTION s/pattern/replace/[opts]'

命令:sed 'SELECTION s/old string/new string/'替换所选区域中第一次出现的old string

命令:sed 'SELECTION s/old string/new string/g'替换所选区域中所有的old string

其中[pots]可以指定选项来控制替换的行为:

  • n:替换行内第n个pattern为replace
  • g:替换行内所有的pattern为replace
  • p:打印这一行,如果替换成功的话.

例如:打印最后四位中前两位是02的串

sed -n '/02[0-9][0-9]$/p' file(s)

其他

如果正在执行字符串替换,并且规则表达式或替换字符串中有许多斜杠,则可以通过在 ‘s’ 之后指定一个不同的字符来更改分隔符。

例如,下例将把所有出现的 /usr/local 替换成 /usr:

$ sed -e 's:/usr/local:/usr:g' mylist.txt

AWK

Awk以逐行方式扫描文件(输入),从第一行到最后一行,以查找匹配某个特定模式的文本行,并对这些文本行执行(括在花括号中的)指定动作。如果只给出模式而未指定动作,则所有匹配改模式的行都显示在屏幕上,如果只指定动作而未定义模式,会对所有输入行执行指定动作。

基本格式:awk '{pattern + action}' {filenames}

工作原理

  • 使用每一行做为输入(文件或者管道),并将这一行赋给内部变量$0,默认是每一行可以称为一个记录,以换行符结束。
  • 每一行被空格分解成字段(单词),每一个字段存储在已经编号的变量中,从$1开始,可以多打100个字段。
  • awk如何知道空格是用来分隔字段的呢?因为有另一个内部变量FS用来确定字段的分隔符。初始时,FS被赋为空格(包含制表符和空格符)。如果需要使用其他的字符分隔字段,如冒号或破折号,则需要将FS 变量的值设为新的字段分隔符。
  • awk打印字段时,将以下面方式使用print函数: awk {print 1,1,3},则输出显示了每个字段使用空格进行分隔,因为在1和1和3之间存在一个逗号。逗号比较特殊,它映射到另外一个内部变量,称之为输出字段分隔符(OFS), OFS默认为空格。逗号被OFS变量中存储的字符替换。
  • awk输出之后,将从文件中获取另一行,并将其存储到$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。这个过程将持续到整个文件的所有行都处理完毕。

使用方式

  • 命令行方式
awk [-F  field-separator]  'commands'  input-file(s)

这里-F是分隔域,是可选的,通常不指定-F分隔域的话,默认的分割域是空格。

  • shell脚本方式 将所有的awk命令插入到一个文件,并使awk程序可执行,首行换成脚本来执行。

#!/bin/sh换成#!/bin/awk

  • 将所有的awk命令插入到一个单独文件,然后调用。
awk -f awk-script-file input-file(s)

print函数

awk命令的操作部分被括在大括号内,如果未指定操作,则匹配到模式时,awk会采取默认操作,在屏幕上打印包含模式的行。print函数用于简单的输出。更为复杂的输出则要使用printf以及sprintf函数,类似于C语言中的函数。

可以用{print}形式在awk命令的动作部分显式地调用print函数,print函数的参数可以是变量数值或是字符串常量。字符串必须使用双引号括起来,参数之间必须使用逗号隔开,如果没有逗号,所有的参数都会被串在一起。

AWK变量

  • 内部变量

变量名称

含义

$0

当前记录(作为单个变量)

1 1~n

当前记录的第n个字段,字段间由FS分隔

FS

输入字段分隔符,默认是空格

NF

当前记录中的字段个数,就是有多少列

NR

已经读出的记录数,就是行号,从1开始

RS

输入的记录分隔符,默认为换行符

OFS

输出字段分隔符,默认也是空格

ORS

输出的记录分隔符,默认为换行符

ARGC

命令行参数个数

ARGV

命令行参数数组

FILENAME

当前输入文件的名字

IGNORECASE

如果为真(非零值),则进行忽略大小写的匹配

ENVIRON

UNIX环境变量

ERRNO

UNIX系统错误消息

#awk  -F ':'  '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd

结果如下:

filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh

$NF表示的是最后一个字段,区别于NF(表示的是当前一共有多少列)

可以使用printf替代print,可以让代码更加简洁

awk  -F ':'  '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
  • 用户自定义变量 awk的变量不用声明其类型,awk可以从变量在表达式中的上下文推导出它的数据类型。如果变量违背初始化,awk会将字符串变量初始化为空串,将数值变量初始化为0。

例如:统计/etc/passwd的账户人数(没有初始化count,默认是0)

awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd

结果如下:

root:x:0:0:root:/root:/bin/bash
......
user count is  40

比较妥当的做法还是初始化0

awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd

结果如下:

[start]user count is  0
root:x:0:0:root:/root:/bin/bash
...
[end]user count is  40

awk工作的流程是先执行BEGIN,然后读取每一条记录,进行操作,最后执行END操作。

AWK脚本

如果awk命令被写在文件里,就要用-f选项指定awk的文件名,后面再加上所要处理的输入文件的文件名。awk从缓冲区读入一条记录,接着测试awk文件中的每一条命令(每条命令都是独立的,这与sed不同),然后对读入的记录执行命令。处理完第一条记录后,awk将其丢弃,接着将下一条记录读入缓冲区,依次处理所有记录。如果没有模式限制,默认的操作就是打印全部记录。而模式如果没有相应的操作,则默认行为是打印匹配它的记录。

ps

linux上进程有5种状态: 1. 运行(正在运行或在运行队列中等待) ,ps中显示状态码为R 2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号) ,ps中显示状态码为S 3. 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生) 4. 僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放),ps中显示状态码为Z 5. 停止(进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行),,ps中显示状态码为T

lsof

lsof(list open files)是一个查看当前系统文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,该文件描述符提供了大量关于这个应用程序本身的信息。

lsof打开的文件可以是: - 普通文件 - 目录 - 网络文件系统的文件 - 字符或设备文件 - (函数)共享库 - 管道,命名管道 - 符号链接 - 网络文件(例如:NFS file、网络socket,unix域名socket) - 还有其它类型的文件,等等

命令参数

  • -a 列出打开文件存在的进程
  • -c<进程名> 列出指定进程所打开的文件
  • -g 列出GID号进程详情
  • -d<文件号> 列出占用该文件号的进程
  • +d<目录> 列出目录下被打开的文件
  • +D<目录> 递归列出目录下被打开的文件
  • -n<目录> 列出使用NFS的文件
  • -i<条件> 列出符合条件的进程。(4、6、协议、:端口、 @ip )
  • -p<进程号> 列出指定进程号所打开的文件
  • -u 列出UID号进程详情
  • -h 显示帮助信息
  • -v 显示版本信息

使用实例

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

  • COMMAND:进程的名称
  • PID:进程标识符
  • PPID:父进程标识符(需要指定-R参数)
  • USER:进程所有者
  • PGID:进程所属组
  • FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等:

查找某个文件相关的进程

$lsof /bin/bash
COMMAND     PID USER  FD   TYPE DEVICE SIZE/OFF    NODE NAME
mysqld_sa  2169 root txt    REG  253,0   938736 4587562 /bin/bash
ksmtuned   2334 root txt    REG  253,0   938736 4587562 /bin/bash
bash      20121 root txt    REG  253,0   938736 4587562 /bin/bash

列出某个用户打开的文件信息

$lsof -u username

列出某个程序进程所打开的文件信息

$lsof -c mysql
类似于
lsof | grep mysql

通过某个进程号显示该进程打开的文件

$lsof -p 11968

列出所有的网络连接

$lsof -i

列出所有tcp 网络连接信息

$lsof -i tcp

列出谁在使用某个端口(冒号和端口之间不能有空格)

$lsof -i :3306

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

$lsof -i 4 -a -p 1234

列出目前连接主机nf5260i5-td上端口为:20,21,80相关的所有文件信息,且每隔3秒重复执行

lsof -i @nf5260i5-td:20,21,80 -r 3

du

Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的。

格式

du [选项][文件]

命令参数

  • -a或-all 显示目录中个别文件的大小。
  • -b或-bytes 显示目录或文件大小时,以byte为单位。
  • -c或–total 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和。
  • -k或–kilobytes 以KB(1024bytes)为单位输出。
  • -m或–megabytes 以MB为单位输出。
  • -s或–summarize 仅显示总计,只列出最后加总的值。
  • -h或–human-readable 以K,M,G为单位,提高信息的可读性。
  • -x或–one-file-xystem 以一开始处理时的文件系统为准,若遇上其它不同的文件系统目录则略过。
  • -L<符号链接>或–dereference<符号链接> 显示选项中所指定符号链接的源文件大小。
  • -S或–separate-dirs 显示个别目录的大小时,并不含其子目录的大小。
  • -X<文件>或–exclude-from=<文件> 在<文件>指定目录或文件。
  • –exclude=<目录或文件> 略过指定的目录或文件。
  • -D或–dereference-args 显示指定符号链接的源文件大小。
  • -H或–si 与-h参数相同,但是K,M,G是以1000为换算单位。
  • -l或–count-links 重复计算硬件链接的文件。

示例:

[root@shield-memsync-svr-3 /home/oicq/r2/tools]# du
1212    ./SHM_KEY
36      ./all_data_id
1192    ./damon_imei_rule
12      ./huiweilv
104     ./lr_v2
8       ./qq_friend_recommd
120     ./report_info_dir
16      ./sparkb5
6016    ./test_load
8840    ./tools_appscore/data
12440   ./tools_appscore
23576   ./tools_auc
1980    ./tools_feeds_lr
6068    ./tools_friend_like
1516    ./tools_load_pool_weight
1508    ./tools_load_push_black_uin
3028    ./tools_load_qq_friend
4       ./tools_qq_friend_recommd
1536    ./tools_qzone_container
20484   ./tools_qzone_feeds
30728   ./tools_qzone_video
10216   ./tools_util
391768  .

注意:只显示当前目录下面的子目录的目录大小和当前目录的总的大小,最下面的391768为当前目录的总大小

常用命令

  • du -sh –max-depth=1 #查看当前目录下所有一级子目录文件夹大小
  • du -h –max-depth=1 |sort #查看当前目录下所有一级子目录文件夹大小 并排序
  • du -h –max-depth=1 |grep ‘G’ |sort #查看上G目录并排序

df

linux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息。

命令格式

df [选项] [文件]

命令参数

必要参数:

  • -a 全部文件系统列表
  • -h 方便阅读方式显示
  • -H 等于“-h”,但是计算式,1K=1000,而不是1K=1024
  • -i 显示inode信息
  • -k 区块为1024字节
  • -l 只显示本地文件系统
  • -m 区块为1048576字节
  • –no-sync 忽略 sync 命令
  • -P 输出格式为POSIX
  • –sync 在取得磁盘信息前,先执行sync命令
  • -T 文件系统类型 选择参数:
  • –block-size=<区块大小> 指定区块大小
  • -t<文件系统类型> 只显示选定文件系统的磁盘信息
  • -x<文件系统类型> 不显示选定文件系统的磁盘信息
  • –help 显示帮助信息
  • –version 显示版本信息

示例1:显示磁盘的使用情况

[root@CT1190 log]# df
文件系统               1K-块        已用     可用 已用% 挂载点
/dev/sda7             19840892    890896  17925856   5% /
/dev/sda9            203727156 112797500  80413912  59% /opt
/dev/sda8              4956284    570080   4130372  13% /var
/dev/sda6             19840892   1977568  16839184  11% /usr
/dev/sda3               988116     23880    913232   3% /boot
tmpfs                 16473212         0  16473212   0% /dev/shm

linux中df命令的输出清单的第1列是代表文件系统对应的设备文件的路径名(一般是硬盘上的分区);第2列给出分区包含的数据块(1024字节)的数目;第3,4列分别表示已用的和可用的数据块数目。用户也许会感到奇怪的是,第3,4列块数之和不等于第2列中的块数。这是因为缺省的每个分区都留了少量空间供系统管理员使用。即使遇到普通用户空间已满的情况,管理员仍能登录和留有解决问题所需的工作空间。清单中Use% 列表示普通用户空间使用的百分比,即使这一数字达到100%,分区仍然留有系统管理员使用的空间。最后,Mounted on列表示文件系统的挂载点。

示例2:以inode形式显示磁盘使用情况

[root@CT1190 log]# df -i
文件系统               Inode (I)已用 (I)可用 (I)已用% 挂载点
/dev/sda7            5124480    5560 5118920    1% /
/dev/sda9            52592640   50519 52542121    1% /opt
/dev/sda8            1280000    8799 1271201    1% /var
/dev/sda6            5124480   80163 5044317    2% /usr
/dev/sda3             255232      34  255198    1% /boot
tmpfs                4118303       1 4118302    1% /dev/shm

示例3:以更易读的方式显示目前磁盘空间和使用情况

root@CT1190 log]# df -h
文件系统              容量  已用 可用 已用% 挂载点
/dev/sda7              19G  871M   18G   5% /
/dev/sda9             195G   89G   96G  49% /opt
/dev/sda8             4.8G  557M  4.0G  13% /var
/dev/sda6              19G  1.9G   17G  11% /usr
/dev/sda3             965M   24M  892M   3% /boot
tmpfs                  16G     0   16G   0% /dev/shm

[root@CT1190 log]# df -k
文件系统               1K-块        已用     可用 已用% 挂载点
/dev/sda7             19840892    890896  17925856   5% /
/dev/sda9            203727156  93292572  99918840  49% /opt
/dev/sda8              4956284    570188   4130264  13% /var
/dev/sda6             19840892   1977568  16839184  11% /usr
/dev/sda3               988116     23880    913232   3% /boot
tmpfs                 16473212         0  16473212   0% /dev/shm

netstat

简介

Netstat 是一款命令行工具,可用于列出系统上所有的网络套接字连接情况,包括 tcp, udp 以及 unix 套接字,另外它还能列出处于监听状态(即等待接入请求)的套接字。如果你想确认系统上的 Web 服务有没有起来,你可以查看80端口有没有打开。以上功能使 netstat 成为网管和系统管理员的必备利器。在这篇教程中,我会列出几个例子,教大家如何使用 netstat 去查找网络连接信息和系统开启的端口号。

常见参数

  • -a (all)显示所有选项,默认不显示LISTEN相关
  • -t (tcp)仅显示tcp相关选项
  • -u (udp)仅显示udp相关选项
  • -n 拒绝显示别名,能显示数字的全部转化成数字。
  • -l 仅列出有在 Listen (监听) 的服務状态
  • -p 显示建立相关链接的程序名
  • -r 显示路由信息,路由表
  • -e 显示扩展信息,例如uid等
  • -s 按各个协议进行统计
  • -c 每隔一个固定时间,执行该netstat命令。

实用命令

1、列出所有的当前的连接

$ netstat -a

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 enlightened:domain      *:*                     LISTEN     
tcp        0      0 localhost:ipp           *:*                     LISTEN     
tcp        0      0 enlightened.local:54750 li240-5.members.li:http ESTABLISHED
tcp        0      0 enlightened.local:49980 del01s07-in-f14.1:https ESTABLISHED
tcp6       0      0 ip6-localhost:ipp       [::]:*                  LISTEN     
udp        0      0 enlightened:domain      *:*                                
udp        0      0 *:bootpc                *:*                                
udp        0      0 enlightened.local:ntp   *:*                                
udp        0      0 localhost:ntp           *:*                                
udp        0      0 *:ntp                   *:*                                
udp        0      0 *:58570                 *:*                                
udp        0      0 *:mdns                  *:*                                
udp        0      0 *:49459                 *:*                                
udp6       0      0 fe80::216:36ff:fef8:ntp [::]:*                             
udp6       0      0 ip6-localhost:ntp       [::]:*                             
udp6       0      0 [::]:ntp                [::]:*                             
udp6       0      0 [::]:mdns               [::]:*                             
udp6       0      0 [::]:63811              [::]:*                             
udp6       0      0 [::]:54952              [::]:*                             
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   Path
unix  2      [ ACC ]     STREAM     LISTENING     12403    @/tmp/dbus-IDgfj3UGXX
unix  2      [ ACC ]     STREAM     LISTENING     40202    @/dbus-vfs-daemon/socket-6nUC6CCx

2、只列出TCP或是UDP协议的连接

使用-t列出TCP连接的协议,使用-u列出UDP连接的协议。

3、禁用反向域名解析,加快查询速度

默认情况下 netstat 会通过反向域名解析技术查找每个 IP 地址对应的主机名。这会降低查找速度。如果你觉得 IP 地址已经足够,而没有必要知道主机名,就使用 -n 选项禁用域名解析功能

$ netstat -ant
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN     
tcp        0      0 192.168.1.2:49058       173.255.230.5:80        ESTABLISHED
tcp        0      0 192.168.1.2:33324       173.194.36.117:443      ESTABLISHED
tcp6       0      0 ::1:631                 :::*                    LISTEN

4、只列出监听中的连接

任何网络服务的后台进程都会打开一个端口,用于监听接入的请求。这些正在监听的套接字也和连接的套接字一样,也能被 netstat 列出来。使用 -l 选项列出正在监听的套接字

$ netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN     
tcp6       0      0 ::1:631                 :::*                    LISTEN

5、获取进程名、进程号以及用户ID

查看端口和连接的信息时,能查看到它们对应的进程名和进程号对系统管理员来说是非常有帮助的。举个栗子,Apache 的 httpd 服务开启80端口,如果你要查看 http 服务是否已经启动,或者 http 服务是由 apache 还是 nginx 启动的,这时候你可以看看进程名。

使用-p选项查看进程信息,**但是必须在root权限下**。

~$ sudo netstat -nlpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN      1144/dnsmasq    
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      661/cupsd       
tcp6       0      0 ::1:631                 :::*                    LISTEN      661/cupsd

strace

简介

strace命令是一个集诊断、调试、统计与一体的工具,我们可以使用strace对应用的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。当然strace与专业的调试工具比如说gdb之类的是没法相比的,因为它不是一个专业的调试器。

常用选项

-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执行被跟踪的命令

基本用法

1、寻找被程序读取的配置文件

raghu@raghu-Linoxide ~ $ strace php 2>&1 | grep php.ini

2、跟踪执行的系统调用

strace命令的-e选项仅仅被用来展示特定的系统调用(例如,open,write等等)。

[chainyang@DSNO_DP_PD_2 ~/small_program]$ strace -e open cat test.sh
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib64/libc.so.6", O_RDONLY)      = 3
open("test.sh", O_RDONLY)               = 3

3、跟踪进程

strace不但能用在命令上,而且通过使用-p选项能用在运行的进程上。

raghu@raghu-Linoxide ~ $ sudo strace -p 1846

4、统计概要

它包括系统调用的概要,执行时间,错误等等。使用-c选项能够以一种整洁的方式展示。

[chainyang@DSNO_DP_PD_2 ~/small_program]$ strace -c ls              
1471511394_edenlei_1105534243.txt.openid  circle.txt  pipe1.cpp  pipe2.cpp  pipe3.cpp  pipe4.cpp  pipe5.cpp  result.txt     sort_by_value.cpp  tranfrom.py      variable_struct.cpp
Makefile                                  pipe1       pipe2      pipe3      pipe4      pipe5      proc.c     sort_by_value  test.sh            variable_struct
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  -nan    0.000000           0        10           read
  -nan    0.000000           0         2           write
  -nan    0.000000           0        11           open
  -nan    0.000000           0        13           close
  -nan    0.000000           0        11           fstat
  -nan    0.000000           0        27           mmap
  -nan    0.000000           0        16           mprotect
  -nan    0.000000           0         3           munmap
  -nan    0.000000           0         3           brk
  -nan    0.000000           0         2           rt_sigaction
  -nan    0.000000           0         1           rt_sigprocmask
  -nan    0.000000           0         2           ioctl
  -nan    0.000000           0         1         1 access
  -nan    0.000000           0         1           execve
  -nan    0.000000           0         1           fcntl
  -nan    0.000000           0         2           getdents
  -nan    0.000000           0         1           getrlimit
  -nan    0.000000           0         1           statfs
  -nan    0.000000           0         1           arch_prctl
  -nan    0.000000           0         2         1 futex
  -nan    0.000000           0         1           set_tid_address
  -nan    0.000000           0         1           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                   113         2 total

5、显示时间戳

-tt选项可以展示微秒级别的时间戳。

raghu@raghu-Linoxide ~ $ strace -tt ls

6、通用用法

strace -o output.txt -T -tt -e trace=all -p 28979

上面这个命令的主要含义就是: 跟踪28979进程的所有系统调用(-e trace=all),并统计系统调用的花费时间,以及开始时间(并以可视化的时分秒格式显示),最后将记录结果存在output.txt文件里面。

pstack

简介

此命令可显示每个进程的栈跟踪。pstack 命令必须由相应进程的属主或 root 运行。可以使用 pstack 来确定进程挂起的位置。此命令允许使用的唯一选项是要检查的进程的 PID

这个命令在排查进程问题时非常有用,比如我们发现一个服务一直处于work状态(如假死状态,好似死循环),使用这个命令就能轻松定位问题所在;可以在一段时间内,多执行几次pstack,若发现代码栈总是停在同一个位置,那个位置就需要重点关注,很可能就是出问题的地方。

查看bash程序进程栈

/opt/app/tdev1$ps -fe| grep bash
tdev1   7013  7012  0 19:42 pts/1    00:00:00 -bash
tdev1  11402 11401  0 20:31 pts/2    00:00:00 -bash
tdev1  11474 11402  0 20:32 pts/2    00:00:00 grep bash
/opt/app/tdev1$pstack 7013
#0  0x00000039958c5620 in __read_nocancel () from /lib64/libc.so.6
#1  0x000000000047dafe in rl_getc ()
#2  0x000000000047def6 in rl_read_key ()
#3  0x000000000046d0f5 in readline_internal_char ()
#4  0x000000000046d4e5 in readline ()
#5  0x00000000004213cf in ?? ()
#6  0x000000000041d685 in ?? ()
#7  0x000000000041e89e in ?? ()
#8  0x00000000004218dc in yyparse ()
#9  0x000000000041b507 in parse_command ()
#10 0x000000000041b5c6 in read_command ()
#11 0x000000000041b74e in reader_loop ()
#12 0x000000000041b2aa in main ()

iconv

iconv命令是用来转换文件的编码方式的,比如它可以将UTF8编码的转换成GB18030的编码,反过来也行。Linux下的iconv开发库包括iconv_open,iconv_close,iconv等C函数,可以用来在C/C++程序中很方便的转换字符编码,这在抓取网页的程序中很有用处,而iconv命令在调试此类程序时用得着。

基本用法

iconv -f encoding [-t encoding] [inputfile]…

选项

  • -f encoding :把字符从encoding编码开始转换。
  • -t encoding :把字符转换到encoding编码。
  • -l :列出已知的编码字符集合。
  • -o file :指定输出文件。
  • -c :忽略输出的非法字符。
  • -s :禁止警告信息,但不是错误信息。
  • –verbose :显示进度信息。
  • -f和-t所能指定的合法字符在-l选项的命令里面都列出来了。

示例

iconv -t gb2312 -f utf-8 -c [file1]

crontab

crontab下关于使用date命令和sudo命令的坑: - 习惯上的date +"%Y%m%d_%H:%M" 和 (date+"(date +"%Y%m%d_%H:%M")在crontab下不起作用,需采用如下形式 `date +"\%Y\%m\%d_\%H:\%M"` 和 (date +”\%Y\%m\%d_\%H:\%M”) - 直接在crontab里以sudo执行命令无效,会提示 sudo: sorry, you must have a tty to run sudo .需要修改/etc/sudoers,执行visudo或者vim /etc/sudoers 将”Defaults requiretty”这一行注释掉。因为sudo默认需要tty终端,而crontab里的命令实际是以无tty形式执行的。注释掉”Defaults requiretty”即允许以无终端方式执行sudo

history

很多时候你需要一遍又一遍执行相同的命令。尽管你可以重复按你键盘上的向上光标键,但你也可以用 history 命令替代。这个命令会列出自从你上次启动终端以来所有输入过的命令:

# history

    1  fdisk -l
    2  apt-get install gnome-paint
    3  hostname tecmint.com
    4  hostnamectl tecmint.com
    5  man hostnamectl 
    6  hostnamectl --set-hostname tecmint.com
    7  hostnamectl -set-hostname tecmint.com
    8  hostnamectl set-hostname tecmint.com
    9  mount -t "ntfs" -o
   10  fdisk -l
   11  mount -t ntfs-3g /dev/sda5 /mnt
   12  mount -t rw ntfs-3g /dev/sda5 /mnt
   13  mount -t -rw ntfs-3g /dev/sda5 /mnt
   14  mount -t ntfs-3g /dev/sda5 /mnt
   15  mount man
   16  man mount
   17  mount -t -o ntfs-3g /dev/sda5 /mnt
   18  mount -o ntfs-3g /dev/sda5 /mnt
   19  mount -ro ntfs-3g /dev/sda5 /mnt
   20  cd /mnt

history会得到一个运行过的命令列表,你可以通过![num]来执行其中的某个命令

uniq

uniq命令可以去除排序过的文件中的重复行,因此uniq经常和sort合用。也就是说,为了使uniq起作用,所有的重复行必须是相邻的

基本使用

uniq [-cdu][-f<栏位>][-s<字符位置>][-w<字符位置>][–help][–version][输入文件][输出文件]

常用选项

 -c, --count              //在每行前加上表示相应行目出现次数的前缀编号  
 -d, --repeated          //只输出重复的行  
 -D, --all-repeated      //只输出重复的行,不过有几行输出几行  
 -f, --skip-fields=N     //-f 忽略的段数,-f 1 忽略第一段  
 -i, --ignore-case       //不区分大小写  
 -s, --skip-chars=N      //根-f有点像,不过-s是忽略,后面多少个字符 -s 5就忽略后面5个字符  
 -u, --unique            //去除重复的后,全部显示出来,根mysql的distinct功能上有点像  
 -w, --check-chars=N      //对每行第N 个字符以后的内容不作对照  

示例

源数据

this is a test  
this is a test  
this is a test  
i am tank  
i love tank  
i love tank  
this is a test  
whom have a try  
WhoM have a try  
you  have a try  
i want to abroad  
those are good men  
we are good men 

每个重复行显示重复次数,但是只检查相邻的行

[zhangy@BlackGhost mytest]$ uniq -c uniqtest  
 3 this is a test  
 1 i am tank  
 2 i love tank  
 1 this is a test           //和第一行是重复的  
 1 whom have a try  
 1 WhoM have a try  
 1 you  have a try  
 1 i want to abroad  
 1 those are good men  
 1 we are good men  

使用sort先排序

[zhangy@BlackGhost mytest]$ sort uniqtest |uniq -c  
 1 WhoM have a try  
 1 i am tank  
 2 i love tank  
 1 i want to abroad  
 4 this is a test  
 1 those are good men  
 1 we are good men  
 1 whom have a try  
 1 you  have a try

只显示重复的行

[zhangy@BlackGhost mytest]$ uniq -d -c uniqtest  
 3 this is a test  
 2 i love tank  

只显示重复的行,但是有几行都输出,不能和-c一起使用

[zhangy@BlackGhost mytest]$ uniq -D uniqtest  
this is a test  
this is a test  
this is a test  
i love tank  
i love tank  

不考虑前4个字符

[zhangy@BlackGhost mytest]$ uniq -s 4 -c uniqtest  
3 this is a test  
1 i am tank  
2 i love tank  
1 this is a test  
3 whom have a try   //根上一个例子有什么不同  
1 i want to abroad  
1 those are good men  
1 we are good men  

rsync

rsync命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。 rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面就对它的选项一一进行分析说明。

tcpdump

普通情况下,直接启动tcpdump将监视第一个网络界面上所有流过的数据包。

tcpdump支持相当多的不同参数,如使用-i参数指定tcpdump监听的网络界面,这在计算机具有多个网络界面时非常有用,使用-c参数指定要监听的数据包数量,使用-w参数指定将监听到的数据包写入文件中保存,等等。

选项介绍

     -a    将网络地址和广播地址转变成名字;
   -d    将匹配信息包的代码以人们能够理解的汇编格式给出;
   -dd    将匹配信息包的代码以c语言程序段的格式给出;
   -ddd   将匹配信息包的代码以十进制的形式给出;
   -e    在输出行打印出数据链路层的头部信息;
   -f    将外部的Internet地址以数字的形式打印出来;
   -l    使标准输出变为缓冲行形式;
   -n    不把网络地址转换成名字;
   -t    在输出的每一行不打印时间戳;
   -v    输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息;
   -vv    输出详细的报文信息;
   -c    在收到指定的包的数目后,tcpdump就会停止;
   -F    从指定的文件中读取表达式,忽略其它的表达式;
   -i    指定监听的网络接口;
   -r    从指定的文件中读取包(这些包一般通过-w选项产生);
   -w    直接将包写入文件中,并不分析和打印出来;
   -T    将监听到的包直接解释为指定的类型的报文,常见的类型有rpc (远程过程调用)和snmp(简单网络管理协议;)
   -s       指定抓包大小

表达式介绍

表达式是一个正则表达式,tcpdump利用它作为过滤报文的条件,如果一个报文满足表达式的条件,则这个报文将会被捕获。如果没有给出任何条件,则网络上所有的信息包将会被截获。在表达式中一般如下几种类型的关键字。

1、类型关键字

主要包括host,net,port

例如host 210.27.48.2指明是一台主机,port 23指明端口。如果没有指定类型,缺省类型是host。

2、传输方法的关键字

主要包括src , dst ,dst or src, dst and src

例如src 210.27.48.2指明ip包中源地址是210.27.48.2,dst net202.0.0.0指明目标网络地址202.0.0.0。如果没有指明方向关键字,则缺省是src or dst。

3、协议关键字

主要包括fddi,ip,arp,rarp,tcp,udp等类型。

示例

   A想要截获所有210.27.48.1 的主机收到的和发出的所有的数据包:

  #tcpdump host 210.27.48.1

  B想要截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信,使用命令:(在命令行中使用括号时,一定要添加'\')

  #tcpdump host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \)

  C如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包,使用命令:

  #tcpdump ip host 210.27.48.1 and ! 210.27.48.2

  D如果想要获取主机210.27.48.1接收或发出的telnet包,使用如下命令:

  #tcpdump tcp port 23 and host 210.27.48.1

  E 对本机的udp 123 端口进行监视 123 为ntp的服务端口

  # tcpdump udp port 123
  
  G 下面的命令可以监视所有送到主机hostname的数据包:

  #tcpdump -i eth0 dst host hostname

参考

http://www.jb51.net/article/60326.htm http://bluebox.blog.51cto.com/8852456/1697552 http://man.linuxde.net/awk http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/lsof.html http://www.cnblogs.com/peida/archive/2012/12/10/2810755.html http://www.brendangregg.com/linuxperf.html http://man.linuxde.net/strace http://www.skorks.com/2010/05/sort-files-like-a-master-with-the-linux-sort-command-bash/ http://blog.jobbole.com/91631/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏xdecode

线程的基本操作

16760
来自专栏技术博客

菜菜从零学习WCF七(消息协定)

    另一种常见方案是定义消息头和正文的安全属性,也就是说,确定是否对这些元素进行数字签名和加密。消息样式的操作可提供这种控制。

9430
来自专栏haifeiWu与他朋友们的专栏

Redis协议规范(译文)

Redis客户端使用名为RESP(Redis序列化协议)的协议与Redis服务器进行通信。 虽然该协议是专为Redis设计的,但它可以用于其他CS软件项目的通讯...

18230
来自专栏开发之途

重拾Java(4)-线程

15740
来自专栏大内老A

[WCF安全系列]绑定、安全模式与客户端凭证类型:WSHttpBinding与WSDualHttpBinding

在上一篇文章中,我们详细地介绍了BasicHttpBinding具有怎样的安全模式的支持,已经在各种安全模式下分别可以采用怎样的客户端凭证。接下来我们来进一步分...

20870
来自专栏码洞

Channel最佳实践之基本规则【译】

channel[通道]是golang的一种重要特性,正是因为channel的存在才使得golang不同于其它语言。channel使得并发编程变得简单容易有趣。

7710
来自专栏python学习路

二、路由、模板

一、路由系统 在settings.py文件中通过ROOT_URLCONF指定根级url的配置 urlpatterns是一个url()实例的列表 一个url()对...

35180
来自专栏Pythonista

vim与程序员

所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在。

19020
来自专栏Danny的专栏

【J2SE快速进阶】——Java多线程机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

10130
来自专栏java一日一条

ava多线程:volatile变量、happens-before关系及内存一致性

请参考来自 Jean-philippe Bempel 的评论。他提到了一个真实因 JVM 优化导致死锁的例子。我尽可能多地写博客的原因之一是一旦自己理解错了,可...

9020

扫码关注云+社区

领取腾讯云代金券