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
- 1
- 2
- 3
- 4
注意:expression 和方括号([ ])之间必须有空格,否则会有语法错误。
if…else也可以写成一行,以命令的方式来运行,像这样:
if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;
- 1
2、if条件表达式中的额外判断
字符串的判断
- str1 = str2 两个字符串有相同内容、长度时为真
- str1 != str2
- -n str1 字符串的长度大于0返回真
- -z str1 字符串的长度等于0时返回真
- str1 字符串为非空返回真
比较两个字符串是否相等的时候,一般的做法是:
if [ "$test"x = "test"x ]; then
- 1
主要考虑以下几点
- 使用单个等号
- 注意到等号两边各有一个空格:这是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 ]
- 1
判断文件大小是否为空
if [ ! -s ${REMOTE_FILE} ]
then
SH_error_msg "${REMOTE_FILE} file is empty"
return 1
fi
- 1
- 2
- 3
- 4
- 5
循环
For
for循环的一般格式为:
for 变量 in 列表
do
command1
command2
...
commandN
done
- 1
- 2
- 3
- 4
- 5
- 6
- 7
列表 是一组值(数字,字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个赋给变量。
in 列表是可选的,如果不用它,for 循环使用命令行的位置参数
- 顺序输出当前列表中的数字
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
- 1
- 2
- 3
- 4
运行结果如下:
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
- 1
- 2
- 3
- 4
- 5
- 1到100输出
for i in {1..100}
do
echo $i
done
- 1
- 2
- 3
- 4
- 显示主目录下以.bash开头的文件
#!/bin/bash
for FILE in $HOME/.bash*
do
echo $FILE
done
- 1
- 2
- 3
- 4
- 5
运行结果如下:
/root/.bash_history
/root/.bash_logout
/root/.bash_profile
/root/.bashrc
- 1
- 2
- 3
- 4
while
while循环的一般格式为:
while 条件语句
do
action
done;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
示例:从文件中读取内容
while read line;do
echo $line;
done < /etc/hosts;
- 1
- 2
- 3
替换
1、命令替换
命令替换$(cmd)
以及`cmd`
$ ls
a b c
$ echo $(ls)
a b c
$ echo `ls`
a b c
- 1
- 2
- 3
- 4
- 5
- 6
对于echo $(ls)
,shell执行时会先执行$(ls)
,得到其标准输出,在用得到输出替换原来位置上的$(ls)
,再执行echo命令。
注意:$(cmd)
中的命令的错误输出是不会被替换的,只有标准输出
$ var=$(cat d)
cat: d
- 1
- 2
这里由于文件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
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
变量
1、shell中0,0,1等变量
- $$:shell本身的PID
- $?:shell最后运行的命令的结束代码
- $*:所有参数列表,如果使用”“括起来的话,会以”11n:添加到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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
运行结果如下:
100
200
- 1
- 2
脚本变量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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
运行结果如下:
(空)
- 1
函数变量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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
运行结果如下:
100
- 1
函数参数是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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
运行结果如下:
100
200
100
- 1
- 2
- 3
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
- 1
- 2
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
- 1
- 2
- 3
- 4
- 5
小技巧:可以使用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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
执行多个命令
使用;
连续不中断执行命令,中间出现错误并不会中断后面命令,例如:
mkdir test; mkdir test; rmdir test;
- 1
虽然第二个命令会出错,但不会影响后面的删除目录命令
使用&&
使用&&
分割的命令,如果没有错误会一直执行下去,出现错误会立即中止,例如:
mkdir test && mkdir test && rmdir test
- 1
这里在第二个命令处就终止了
使用||
使用||
分隔的命令,如果有错误就一直执行下去,直到一次正确的执行就立即终止,例如:
mkdir test || mkdir test || rmdir test
mkdir test || mkdir test || rmdir test || mkdir test
- 1
- 2
第一次执行第一条指令就正确,后面的不执行
第二次执行前两条都错误,直到最后一条才正确,最后一条不再执行
多个命令构成一个数组,然后批量执行
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
正则表达式
使用[]
搜索集合字符
[chainyang@DSNO_DP_PD_2 ~/small_program]$ grep '[ae]st' test.txt --color=auto
past
test
best
- 1
- 2
- 3
- 4
可以用^符号做[]内的前缀,表示除[]内的字符之外的字符。
而如果^符号不再[]内,那么就可以用来表示开头,$表示结尾。
搜索以小写字母开头的行
grep -n '^[a-z]' regular_express.txt
- 1
搜索开头不是英文字母的行
grep -n '^[^a-zA-Z]' regular_express.txt
- 1
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
上述示例中-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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
Sed
基本命令
sed的一般命令格式如下:
sed [options] [commands] filename
- 1
更详细的命令格式如下:
sed [OPTION]... '抓取条件/编辑命令' [input-file]...
- 1
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)
- 1
其他
如果正在执行字符串替换,并且规则表达式或替换字符串中有许多斜杠,则可以通过在 ‘s’ 之后指定一个不同的字符来更改分隔符。
例如,下例将把所有出现的 /usr/local 替换成 /usr:
$ sed -e 's:/usr/local:/usr:g' mylist.txt
- 1
AWK
Awk以逐行方式扫描文件(输入),从第一行到最后一行,以查找匹配某个特定模式的文本行,并对这些文本行执行(括在花括号中的)指定动作。如果只给出模式而未指定动作,则所有匹配改模式的行都显示在屏幕上,如果只指定动作而未定义模式,会对所有输入行执行指定动作。
基本格式:awk '{pattern + action}' {filenames}
工作原理
使用每一行做为输入(文件或者管道),并将这一行赋给内部变量$0,默认是每一行可以称为一个记录,以换行符结束。
每一行被空格分解成字段(单词),每一个字段存储在已经编号的变量中,从$1开始,可以多打100个字段。
awk如何知道空格是用来分隔字段的呢?因为有另一个内部变量FS用来确定字段的分隔符。初始时,FS被赋为空格(包含制表符和空格符)。如果需要使用其他的字符分隔字段,如冒号或破折号,则需要将FS 变量的值设为新的字段分隔符。
awk打印字段时,将以下面方式使用print函数: awk {print 1,1,3之间存在一个逗号。逗号比较特殊,它映射到另外一个内部变量,称之为输出字段分隔符(OFS), OFS默认为空格。逗号被OFS变量中存储的字符替换。
awk输出之后,将从文件中获取另一行,并将其存储到$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。这个过程将持续到整个文件的所有行都处理完毕。
使用方式
- 命令行方式
awk [-F field-separator] 'commands' input-file(s)
- 1
这里-F是分隔域,是可选的,通常不指定-F分隔域的话,默认的分割域是空格。
- shell脚本方式
将所有的awk命令插入到一个文件,并使awk程序可执行,首行换成脚本来执行。
即#!/bin/sh
换成#!/bin/awk
- 将所有的awk命令插入到一个单独文件,然后调用。
awk -f awk-script-file input-file(s)
- 1
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
- 1
结果如下:
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
- 1
- 2
- 3
- 4
$NF表示的是最后一个字段,区别于NF(表示的是当前一共有多少列)
可以使用printf替代print,可以让代码更加简洁
awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
- 1
- 用户自定义变量
awk的变量不用声明其类型,awk可以从变量在表达式中的上下文推导出它的数据类型。如果变量违背初始化,awk会将字符串变量初始化为空串,将数值变量初始化为0。
例如:统计/etc/passwd的账户人数(没有初始化count,默认是0)
awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
- 1
结果如下:
root:x:0:0:root:/root:/bin/bash
......
user count is 40
- 1
- 2
- 3
比较妥当的做法还是初始化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
- 1
结果如下:
[start]user count is 0
root:x:0:0:root:/root:/bin/bash
...
[end]user count is 40
- 1
- 2
- 3
- 4
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
- 1
- 2
- 3
- 4
- 5
列出某个用户打开的文件信息
$lsof -u username
- 1
列出某个程序进程所打开的文件信息
$lsof -c mysql
类似于
lsof | grep mysql
- 1
- 2
- 3
通过某个进程号显示该进程打开的文件
$lsof -p 11968
- 1
列出所有的网络连接
$lsof -i
- 1
列出所有tcp 网络连接信息
$lsof -i tcp
- 1
列出谁在使用某个端口(冒号和端口之间不能有空格)
$lsof -i :3306
- 1
列出被进程号为1234的进程所打开的所有IPV4 network files
$lsof -i 4 -a -p 1234
- 1
列出目前连接主机nf5260i5-td上端口为:20,21,80相关的所有文件信息,且每隔3秒重复执行
lsof -i @nf5260i5-td:20,21,80 -r 3
- 1
du
Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的。
格式
du [选项][文件]
- 1
命令参数
- -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 .
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
注意:只显示当前目录下面的子目录的目录大小和当前目录的总的大小,最下面的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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
示例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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
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
- 1
- 2
- 3
- 4
- 5
- 6
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
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
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
基本用法
1、寻找被程序读取的配置文件
raghu@raghu-Linoxide ~ $ strace php 2>&1 | grep php.ini
- 1
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
- 1
- 2
- 3
- 4
3、跟踪进程
strace不但能用在命令上,而且通过使用-p选项能用在运行的进程上。
raghu@raghu-Linoxide ~ $ sudo strace -p 1846
- 1
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
5、显示时间戳
-tt选项可以展示微秒级别的时间戳。
raghu@raghu-Linoxide ~ $ strace -tt ls
- 1
6、通用用法
strace -o output.txt -T -tt -e trace=all -p 28979
- 1
上面这个命令的主要含义就是: 跟踪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 ()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
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]
- 1
crontab
crontab下关于使用date命令和sudo命令的坑:
- 习惯上的date +"%Y%m%d_%H:%M"
和 (date+"(date+"(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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
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 个字符以后的内容不作对照
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
示例
源数据
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
每个重复行显示重复次数,但是只检查相邻的行
[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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
使用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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
只显示重复的行
[zhangy@BlackGhost mytest]$ uniq -d -c uniqtest
3 this is a test
2 i love tank
- 1
- 2
- 3
只显示重复的行,但是有几行都输出,不能和-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
- 1
- 2
- 3
- 4
- 5
- 6
不考虑前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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
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 指定抓包大小
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
表达式介绍
表达式是一个正则表达式,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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
参考
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/