Shell共有三种三种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;
比较两个字符串是否相等的时候,一般的做法是:
if [ "$test"x = "test"x ]; then
主要考虑以下几点
判断/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 变量 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
for i in {1..100}
do
echo $i
done
#!/bin/bash
for FILE in $HOME/.bash*
do
echo $FILE
done
运行结果如下:
/root/.bash_history
/root/.bash_logout
/root/.bash_profile
/root/.bashrc
while循环的一般格式为:
while 条件语句
do
action
done;
示例:从文件中读取内容
while read line;do
echo $line;
done < /etc/hosts;
命令替换$(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在当前目录不存在
()
和{}
都是对一串的命令进行执行,但是有所区别:
()
只是对一串命令重新开一个子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
∗和*和@在不加引号的时候,都可以表示一个参数数组;而在加了引号之后,”∗"就表示一个参数字符串,而"*"就表示一个参数字符串,而"@”依然表示一个参数数组
${var%pattern},表示从变量$var的结尾删除最短匹配pattern的子串
${0%/*}
表示删除从变量0尾部开始第一个‘/‘之后匹配的内容,比如0尾部开始第一个`/`之后匹配的内容,比如0是这个目录/home/john/source 那么就是把”/source”截取掉,剩下/home/john,一般用来获取当前执行脚本的目录
#!/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
。
#!/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的作用域内。
#!/bin/bash
#define the function ltx_func
ltx_func()
{
echo "param 1: $1"
}
#call the function ltx_func
ltx_func 100
运行结果如下:
100
函数参数是local的,通过位置变量$1
来访问
#!/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 9 + 8 - 7 \* 6 / 5 + \( 4 - 3 \) \* 2
11
expr同时还可以对字符串进行操作: - match 字符串 表达式等于”字符串 :表达式” - substr 字符串 偏移量 长度替换字符串的子串,偏移的数值从 1 起计 - index 字符串 字符在字符串中发现字符的地方建立下标,或者标0 - length 字符串字符串的长度
上面我们介绍的expr之支持整数运算,但对于浮点运算就无能为力了,而且expr不能进行指数运算,而都有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在一个或多个文件中查找与模式字符串(pattern)匹配的行,并将搜索的结果打印出来,不会修改原文件内容。 使用grep 命令的语法为: grep [option] pattern [file(s)]
-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命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。sort命令既可以从特定的文件,也可以从stdin中获取输入。
sort(选项)(参数)
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指定栏位分隔符为冒号。
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 [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中的字符串只是用于临时处理的中间结果,是不会被输出的。
sed不会对文件中的每一行做action,只会把符合条件的行送入模式空间来进行处理。
抓取条件通常有地址定界以及正则寻址两种配合使用。
1、地址定界
1
为取第一行,5
为取第五行,$
为取最后一行1,3
表示闭区间从第一行到第三行,如1~2
中~
表示的步长,即第一行,第三行,第五行2、正则寻址
/string/
为抓取包含string的行/^on/,/off$/
为抓取从on开头到off结尾的行之间(包含这两个匹配行)的文本10,/string/
表示从第10行到第一次匹配到string的行之间的文本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]可以指定选项来控制替换的行为:
例如:打印最后四位中前两位是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 '{pattern + action}' {filenames}
awk [-F field-separator] 'commands' input-file(s)
这里-F是分隔域,是可选的,通常不指定-F分隔域的话,默认的分割域是空格。
即#!/bin/sh
换成#!/bin/awk
awk -f awk-script-file input-file(s)
awk命令的操作部分被括在大括号内,如果未指定操作,则匹配到模式时,awk会采取默认操作,在屏幕上打印包含模式的行。print函数用于简单的输出。更为复杂的输出则要使用printf以及sprintf函数,类似于C语言中的函数。
可以用{print}形式在awk命令的动作部分显式地调用print函数,print函数的参数可以是变量,数值或是字符串常量。字符串必须使用双引号括起来,参数之间必须使用逗号隔开,如果没有逗号,所有的参数都会被串在一起。
变量名称 | 含义 |
---|---|
$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
例如:统计/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命令被写在文件里,就要用-f选项指定awk的文件名,后面再加上所要处理的输入文件的文件名。awk从缓冲区读入一条记录,接着测试awk文件中的每一条命令(每条命令都是独立的,这与sed不同),然后对读入的记录执行命令。处理完第一条记录后,awk将其丢弃,接着将下一条记录读入缓冲区,依次处理所有记录。如果没有模式限制,默认的操作就是打印全部记录。而模式如果没有相应的操作,则默认行为是打印匹配它的记录。
linux上进程有5种状态: 1. 运行(正在运行或在运行队列中等待) ,ps中显示状态码为R 2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号) ,ps中显示状态码为S 3. 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生) 4. 僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放),ps中显示状态码为Z 5. 停止(进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行),,ps中显示状态码为T
lsof(list open files)是一个查看当前系统文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,该文件描述符提供了大量关于这个应用程序本身的信息。
lsof打开的文件可以是: - 普通文件 - 目录 - 网络文件系统的文件 - 字符或设备文件 - (函数)共享库 - 管道,命名管道 - 符号链接 - 网络文件(例如:NFS file、网络socket,unix域名socket) - 还有其它类型的文件,等等
lsof输出各列信息的意义如下:
查找某个文件相关的进程
$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
Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的。
du [选项][文件]
示例:
[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为当前目录的总大小
linux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息。
df [选项] [文件]
必要参数:
示例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 是一款命令行工具,可用于列出系统上所有的网络套接字连接情况,包括 tcp, udp 以及 unix 套接字,另外它还能列出处于监听状态(即等待接入请求)的套接字。如果你想确认系统上的 Web 服务有没有起来,你可以查看80端口有没有打开。以上功能使 netstat 成为网管和系统管理员的必备利器。在这篇教程中,我会列出几个例子,教大家如何使用 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与专业的调试工具比如说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 命令必须由相应进程的属主或 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命令是用来转换文件的编码方式的,比如它可以将UTF8编码的转换成GB18030的编码,反过来也行。Linux下的iconv开发库包括iconv_open,iconv_close,iconv等C函数,可以用来在C/C++程序中很方便的转换字符编码,这在抓取网页的程序中很有用处,而iconv命令在调试此类程序时用得着。
iconv -f encoding [-t encoding] [inputfile]…
iconv -t gb2312 -f utf-8 -c [file1]
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
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经常和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命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。 rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面就对它的选项一一进行分析说明。
普通情况下,直接启动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/