linux lsof 命令

lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接 和硬件。所以如传输控制协议 (tcp) 和用户数据报协议 (udp) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因 为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。
lsof使用
lsof输出信息含义
在终端下输入lsof即可显示系统打开的文件,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。
command    pid      user   fd      type     device     size       node      name
init       1         root cwd      dir       3,3       1024       2         /
init       1         root rtd      dir       3,3       1024       2         /
init       1         root txt      reg       3,3       38432      1763452 /sbin/init
init       1         root mem      reg       3,3       106114     1091620 /lib/libdl-2.6.so
init       1         root mem      reg       3,3       7560696    1091614 /lib/libc-2.6.so
init       1         root mem      reg       3,3       79460      1091669 /lib/libselinux.so.1
init       1         root mem      reg       3,3       223280     1091668 /lib/libsepol.so.1
init       1         root mem      reg       3,3       564136     1091607 /lib/ld-2.6.so
init       1         root 10u      fifo      0,15                  1309     /dev/initctl
每行显示一个打开的文件,若不指定条件默认将显示所有进程打开的所有文件。lsof输出各列信息的意义如下:
command:进程的名称
pid:进程标识符
user:进程所有者
fd:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
type:文件类型,如dir、reg等
device:指定磁盘的名称
size:文件的大小
node:索引节点(文件在磁盘上的标识)
name:打开文件的确切名称
其中fd 列中的文件描述符cwd 值表示应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改。
txt 类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序。其次数值表示应用
程序的文件描述符,这是打开该文件时返回的一个整数。如上的最后一行文件/dev/initctl,其文件描述符为 10。u 表示该
文件被打开并处于读取/写入模式,而不是只读 ® 或只写 (w) 模式。同时还有大写 的w 表示该应用程序具有对整个文件的写
锁。该文件描述符用于确保每次只能打开一个应用程序实例。初始打开每个应用程序时,都具有三个文件描述符,从 0 到 2,
分别表示标准输入、输出和错误流。所以大多数应用程序所打开的文件的 fd 都是从 3 开始。
与 fd 列相比,type 列则比较直观。文件和目录分别称为 reg 和 dir。而chr 和 blk,分别表示字符和块设备;
或者 unix、fifo 和 ipv4,分别表示 unix 域套接字、先进先出 (fifo) 队列和网际协议 (ip) 套接字。
lsof常用参数
lsof 常见的用法是查找应用程序打开的文件的名称和数目。可用于查找出某个特定应用程序将日志数据记录到何处,或者正在跟踪某个问题。
例如,linux限制了进程能够打开文件的数目。通常这个数值很大,所以不会产生问题,并且在需要时,应用程序可以请求更大的值(直到某
个上限)。如果你怀疑应用程序耗尽了文件描述符,那么可以使用 lsof 统计打开的文件数目,以进行验证。lsof语法格式是:
lsof [options] filename
常用的参数列表:
lsof filename 显示打开指定文件的所有进程
lsof -a 表示两个参数都必须满足时才显示结果
lsof -c string   显示command列中包含指定字符的进程所有打开的文件
lsof -u username 显示所属user进程打开的文件
lsof -g gid 显示归属gid的进程情况
lsof +d /dir/ 显示目录下被进程打开的文件
lsof +d /dir/ 同上,但是会搜索目录下的所有目录,时间相对较长
lsof -d fd 显示指定文件描述符的进程
lsof -n 不将ip转换为hostname,缺省是不加上-n参数
lsof -i 用以显示符合条件的进程情况
lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
           46 --> ipv4 or ipv6
           protocol --> tcp or udp
           hostname --> internet host name
           hostaddr --> ipv4地址
           service --> /etc/service中的 service name (可以不只一个)
           port --> 端口号 (可以不只一个)
例如: 查看22端口现在运行的情况
# lsof -i :22
command pid user   fd   type device size node name
sshd    1409 root    3u ipv6   5678       tcp *:ssh (listen)
查看所属root用户进程所打开的文件类型为txt的文件:
# lsof -a -u root -d txt
command    pid user fd      type device    size    node name
init       1    root txt       reg    3,3   38432 1763452 /sbin/init
mingetty 1632 root txt       reg    3,3   14366 1763337 /sbin/mingetty
mingetty 1633 root txt       reg    3,3   14366 1763337 /sbin/mingetty
mingetty 1634 root txt       reg    3,3   14366 1763337 /sbin/mingetty
mingetty 1635 root txt       reg    3,3   14366 1763337 /sbin/mingetty
mingetty 1636 root txt       reg    3,3   14366 1763337 /sbin/mingetty
mingetty 1637 root txt       reg    3,3   14366 1763337 /sbin/mingetty
kdm        1638 root txt       reg    3,3 132548 1428194 /usr/bin/kdm
x          1670 root txt       reg    3,3 1716396 1428336 /usr/bin/xorg
kdm        1671 root txt       reg    3,3 132548 1428194 /usr/bin/kdm
startkde 2427 root txt       reg    3,3 645408 1544195 /bin/bash
... ...

用Shell编程,判断一文件是不是块或字符设备文件,如果是将其拷贝到 /dev 目录下。

如题:
答案如下:
#!/bin/bash
read -p "Input a filename : " filename
if [ -b "$filename" -o -c "$filename" ]
then
       echo "$filename is a device file" && cp $filename /dev/ &
else
       echo "$filename is not a device file" && exit 1
fi

用脚本关闭linux不用的服务

#! /bin/bash

services=`chkconfig --list|awk '{print $1}'`
for ser in $services
do
if [ "$ser" == "network" ] || [ "$ser" == "syslog" ] || [ "$ser" == "sshd" ] || \
[ "$ser" == "crond" ] || [ "$ser" == "atd" ] || [ "$ser" == "irqbalance" ] || \
[ "$ser" == "microcode_ctl" ] || [ "$ser" == "sendmail" ] ;
then
chkconfig --leve 3 "$ser" on
else
chkconfig "$ser" off
fi
done
echo "The unavaliable service has been shutdown successfully!"
sleep 5
init 6

编写一个shell程序,将文件的.txt后缀名删除的程序

答案一:
#!/bin/bash
for i in `ls *.txt`
do
p=`echo $i|awk -F. '{print $1}'`
mv $i $p
done

答案二:find -type f -name '*.txt' -print0 | xargs --null rename '.txt' ''

awk 合并一个文件

我有这样的需求,需要把两个文件中,第一列相同的行合并到同一行中。举个例子,有两个文件,内容如下
cat 1.txt
1 aa
2 bb
3 ee
4 ss

cat 2.txt
1 ab
2 cd
3 ad
4 bd
5 de

合并后的结果为:

1 ab aa
2 cd bb
3 ad ee
4 bd ss
5 de

实现的命令为:
awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}'  1.txt  2.txt

解释:NR表示读取的行数,FNR表示读取的当前行数
所以其实NR==FNR 就表示读取2.txt的时候。 同理NR>FNR表示读取1.txt的时候
数组a其实就相当于一个map

split 分割大文件指定输出文件名

split 用做分割文件,你可以按照大小分割,也可以按照行数分割。
比如:
split  -l  10000   filename   
这个是依据行数来分割的,每10000行为一个小文件

split  -b  1m  filename   
这是按照大小来分割的,每1m为一个小文件

默认情况下,如果我们不指定输出的文件名,会以这样的形式出现在当前目录下 :  xaa  xab .... xaz xba xbb ... xbz  
那么如何指定输出的文件名字呢?
只需要这样即可:
split  -l  10000  filename   outfilename   
这里的outfilename 就为你指定的输出文件名,不过分割后的文件名为   outfilenameaa   outfilenameab ...

用shell编程,写一个筛出10001--20000范围内的质数的程序,可以用FOR循环

质数是指:在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。换句话说,只有两个正因数(1和自己)的自然数

#!/bin/sh
for((i=10000;i<=12000;i++))
do
        for((k=2;k<=i;k++))
        do
                if [ $k -eq $i ]
                then
                        echo "$i su shu"
                        break

                fi
                if [ $(($i%k)) -eq 0 ]
                then break
                fi
        done
done

随机生成字符串

dd if=/dev/random count=16 bs=1| xxd -ps   //32位

dd if=/dev/random count=24 bs=1| xxd -ps   //48位

除百度、Google外其他蜘蛛IP封锁脚本

本帖隐藏的内容需要回复才可以浏览

awk 中使用外部shell变量

如:
A=44
echo "ABCD" | awk -v GET_A=$A ’{print GET_A}’

说明:-v选项用于定义参数,这里表示将变量A的值赋予GET_A。有多少个变量需要赋值,就需要多少个-v选项。与之等价的:

应用于脚本中:
#! /bin/bash

sort -n filename |awk -F ':' '{print $1}'|uniq >id.txt
for id in `cat id.txt`; do
        echo "[$id]"
        awk -v id2=$id -F ':' '$1==id2 {print $2}' filename  // 另外的方式为: awk -F ':' '$1=="'id2'" {print $2}' filename  
done

附件:
cat filename
1111111:13443253456
2222222:13211222122
1111111:13643543544
3333333:12341243123
2222222:12123123123

运行脚本后结果为:
[1111111]
13443253456
13643543544
[2222222]
13211222122
12123123123
[3333333]
12341243123

其他关于awk相关文章

linux shell下得到指定字符串的md5加密字符串

echo test |md5sum|awk '{print $1}'

结果是
d8e8fca2dc0f896fd7cb4cb0031ba249

用shell脚本判断某个日志5分钟有没有变更

#! /bin/bash
## 判断日志在5分钟内有没有更改
## Writen by Aming.

logfile="/var/log/messages"
l=`find $logfile -mmin -5|wc -l`
if [ "$l" -eq "0" ] ; then
        echo "日志5分钟内没有变更."
else
        echo "日志5分钟内有变更."
fi

封灌水机ip脚本

#! /bin/bash

## This script if for kill post robots.
## Writen by Li Shiming 2010-08-19.

while :; do
logf=/home/logs/client/access.log
tmplog=/tmp/tmplog.txt
ipf=/tmp/killpost.ip
badipf=/var/log/badip.log
conf=/etc/killpost.conf
n1=`grep 'n1=' $conf|awk -F'=' '{print $2}' `
n2=`grep 'n2=' $conf|awk -F'=' '{print $2}' `
n3=`grep 'n3=' $conf|awk -F'=' '{print $2}' `

/sbin/iptables -nvL |grep REJECT |grep tcp |grep 80 |awk '$1<10 {print $8}'|grep -v '0.0.0.0' |xargs -n1 -i{} /sbin/iptables -D INPUT -s {} -p tcp --dport 80 -j REJECT
/sbin/iptables -Z

for i in 1 2; do

        tail -n $n1 $logf >$tmplog

        cat $tmplog | grep 'submit' |awk '$6~/\/post.*php?/ {print $1}' |grep -v '192.168.0.' |grep -v '192.168.4.'|grep -v '127.0.0.'|grep -v '121.10.121.' |grep -v '124.238.249.' |grep -v '221.194.139.' | grep -v '124.238.246.' |grep -v '124.207.144.194'|grep -v '124.238.252.'|sort -n |uniq -c |sort -n |awk '$1>"'$n2'" {print $2}'>$ipf

        for ip in `cat $ipf`; do
           n=`grep $ip $tmplog |awk '{print $5}'|grep -v '-' |sort |uniq |wc -l`
           if [ $n -gt 2 ] ; then
                /sbin/iptables -I INPUT -s $ip -p tcp --dport 80 -j REJECT
                echo  $ip >>$badipf
           fi
        done
        sort -n $badipf |uniq >/tmp/tmp.log
        cat /tmp/tmp.log >$badipf
        sleep $n3
done

sleep $n3

done

bash快捷键

ctrl+p: 方向键 上 ↑
ctrl+n: 方向键下 ↓
ctrl+b: 方向键 ←
alt+f: 光标右移一个单词
ctrl+f :方向键 →
alt+b: 光标左移一个单词
ctrl+a:光标移到行首
ctrl+e:光标移到行尾
ctrl+k:清除光标后至行尾的内容。
ctrl+d: 删除光标所在字母;注意和backspace以及ctrl+h的区别,这2个是删除光标前的字符
ctrl+r:搜索之前打过的命令。会有一个提示,根据你输入的关键字进行搜索bash的history
ctrl+m : 输入回车
ctrl+i : 输入tab
ctrl+[ : 输入esc
ctrl+h:删除光标前一个字符,同 backspace 键相同。
alt + p 非增量方式反向搜索历史
alt + > 历史命令列表中的最后一行命令开始向前
ctrl+u: 清除光标前至行首间的所有内容。
ctrl+w: 移除光标前的一个单词
ctrl+t: 交换光标位置前的两个字符
ctrl+y: 粘贴或者恢复上次的删除
ctrl+l:清屏,相当于clear。
ctrl + xx 光标在行头与行尾进行跳转
alt+r 撤销当前行的所有内容
ctrl+z : 把当前进程转到后台运行
ctrl+s : 锁住屏幕
ctrl+q : 恢复屏幕
ctrl+v key: 输入特殊字符
alt + l 将当前光标处之后的字母转化成小写字母
alt + u 将当前光标处之后的字母转化成大写字母
ctrl + Alt + e 扩展命令行的内容(例如:ls => ls -l --color=tty)
ctrl+c:杀死当前进程, 输入模式下,中断输入的命令。
ctrl+d:退出当前 Shell

【求助】iptables重启后的问题

今天在VPS上测试一个iptables规则,很奇怪的问题,明明放行了22端口,防火墙启动后还是拦截了22端口,随后reboot了一下服务器,现在远程连接不上了,郁闷中.......,把shell脚本贴上来,希望大家帮忙看下哪里出了问题,谢谢额~~#!/bin/bash

ipt=/sbin/iptables

$ipt -F OUTPUT
$ipt -F FORWARD
$ipt -F INPUT
$ipt -X OUTPUT
$ipt -X INTPUT
$ipt -X FORWARD
$ipt -P INPUT DROP
$ipt -P OUTPUT ACCEPT
$ipt -P FORWARD DROP
$ipt -A INPUT -p tcp --dport 22 -j ACCEPT
$ipt -A INPUT -p tcp --dport 20 -j ACCEPT
$ipt -A INPUT -p tcp --dport 80 -j ACCEPT
$ipt -A INPUT -p tcp --dport 21 -j ACCEPT
$ipt -A INPUT -p udp --dport 22 -j ACCEPT
$ipt -A INPUT -p udp --dport 20 -j ACCEPT
$ipt -A INPUT -p udp --dport 80 -j ACCEPT
$ipt -A INPUT -p udp --dport 21 -j ACCEPT
$ipt -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$ipt -A INPUT -m state --state INVALID -j DROP
/sbin/service iptables save
/sbin/service iptables restart
exit 0
系统为centos 5.5
等iptables重启完成后,执行iptables -L看到也达到了预期的效果,input为drop,22  21  80 端口都在允许列表,cat /etc/sysconfig/iptables也看到了相应的规则,好几次了都是把自己挡在外边了,不知道是顺序还是哪里出了问题,希望大家可以指教,谢谢!!!