netsat
如果我这样使用,后缀守护进程只有名称“master” :
root@myhost# netstat -tulpen| grep master
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 53191445 13640/master
如果我使用ps
我会得到一个更详细的名称:
root@myhost# ps aux| grep 13640
root 13640 0.0 0.0 25036 1500 11:35 0:00 /usr/lib/postfix/master
有没有办法告诉netstat
输出长名称?
在这种情况下,它会是/usr/lib/postfix/master
。
更新
看来netstat做不到。如果您知道如何使用其他工具执行此操作,那么这也是一个有效的问题。 (但基于 netstat 的解决方案仍然是首选)。
更新2
所有答案都有效。非常感谢您展示您的 UNIX 知识。但到目前为止,答案太长/太复杂。
难道就没有简单的解决办法吗?我可以安装任何需要的工具,但我希望用法简单易用。
我不能把赏金给你们所有人...
有几个答案可以进行后处理以获得所需的信息。每个答案都使用不同的方式,我不认为一种解决方案比另一种更好。
不幸的是,似乎没有unix/linux 可以开箱即用地做到这一点。但这不是你的错,你试图帮助我。
不幸的是,我无法为所有答案提供赏金:-)
我把赏金给了信誉点最低的用户。
答案1
这是我一段时间以来对“优雅”解决方案最有趣的搜索。谢谢。
一般评论:
与解析相比/proc/pid/cmdline
,运行更有意义readlink /proc/pid/exe
。
它看起来像什么:
我设置了一个 shell 函数full
来抽象出其中的复杂性——主要是为了节省打字时间。
唯一的依赖是符合 POSIX 标准ex
和Linux标准readlink
。
head
为了简洁起见,我在下面的终端输出中进行了管道传输。
[root@localhost ~]# netstat -tulpen | head
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 9581 1237/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 10164 1493/master
tcp 0 0 0.0.0.0:555 0.0.0.0:* LISTEN 0 14326 2824/nc
tcp 0 0 0.0.0.0:46638 0.0.0.0:* LISTEN 29 8848 960/rpc.statd
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 0 8749 940/rpcbind
tcp 0 0 :::22 :::* LISTEN 0 9583 1237/sshd
tcp 0 0 ::1:25 :::* LISTEN 0 10166 1493/master
tcp 0 0 :::47166 :::* LISTEN 29 8856 960/rpc.statd
[root@localhost ~]# netstat -tulpen | head | full
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 9581 1237/usr/sbin/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 10164 1493/usr/libexec/postfix/master
tcp 0 0 0.0.0.0:555 0.0.0.0:* LISTEN 0 14326 2824/usr/bin/nc
tcp 0 0 0.0.0.0:46638 0.0.0.0:* LISTEN 29 8848 960/sbin/rpc.statd
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 0 8749 940/sbin/rpcbind
tcp 0 0 :::22 :::* LISTEN 0 9583 1237/usr/sbin/sshd
tcp 0 0 ::1:25 :::* LISTEN 0 10166 1493/usr/libexec/postfix/master
tcp 0 0 :::47166 :::* LISTEN 29 8856 960/sbin/rpc.statd
[root@localhost ~]#
它也适用于任何形式的netstat -p
,甚至是在某些行上有其他尾随数据的形式:
[root@localhost ~]# netstat -p | head
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 10.0.2.15:ssh 10.0.2.2:63550 ESTABLISHED 2557/sshd
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags Type State I-Node PID/Program name Path
unix 11 [ ] DGRAM 8584 895/rsyslogd /dev/log
unix 2 [ ] DGRAM 9124 1045/hald @/org/freedesktop/hal/udev_event
unix 2 [ ] DGRAM 7116 340/udevd @/org/kernel/udev/udevd
unix 2 [ ] DGRAM 16523 3537/pickup
unix 2 [ ] DGRAM 15036 2865/su
[root@localhost ~]# netstat -p | head | full
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 10.0.2.15:ssh 10.0.2.2:63550 ESTABLISHED 2557/usr/sbin/sshd
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags Type State I-Node PID/Program name Path
unix 11 [ ] DGRAM 8584 895/sbin/rsyslogd /dev/log
unix 2 [ ] DGRAM 9124 1045/usr/sbin/hald @/org/freedesktop/hal/udev_event
unix 2 [ ] DGRAM 7116 340/sbin/udevd @/org/kernel/udev/udevd
unix 2 [ ] DGRAM 16523 3537/usr/libexec/postfix/pickup
unix 2 [ ] DGRAM 15036 2865/bin/su
[root@localhost ~]#
它是如何定义的:
[root@localhost ~]# type full
full is a function
full ()
{
ex -c 'g/^.*\(\<[0-9]\+\)\/.*$/ya|pu|s::readlink /proc/\1/exe:|.!sh' -c 'g/^\//-ya|pu|-2s/^\(.*\<[0-9]\+\)\/[^[:space:]]*\(.*\)$/\1/|+2s//\2/|-2j!3' -c%p -c 'q!' /dev/stdin
}
[root@localhost ~]#
它是如何工作的(逐步分解):
(即将推出;同时尝试一下,让我知道您是否喜欢它。)
答案2
正如您已经想到的那样,netstat
默认情况下无法提供带有选项cmdline
的完整输出-p
。根据消息来源,它似乎仅限于20 个字符并且仅列出完整命令行的一部分
您可以围绕 netstat 编写自己的包装器来显示完整的详细信息。添加了下面的 python 代码片段,显示完整的 cmd 行。
#!/usr/bin/env python
from subprocess import Popen,PIPE
out,err = Popen(['netstat','-antlp'],stdout=PIPE).communicate()
for l in out.splitlines():
line = l.split()
if '/' in line[-1]:
p = line[-1].split('/')[0]
line[-1] = str(p) + ' -> ' + open('/proc/'+p+'/cmdline','r').readline().split('-')[0]
print '\t'.join(line)
示例输出:
$ sudo ./netstat.py
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:11443 0.0.0.0:* LISTEN 4007 -> /usr/sbin/apache2
tcp 0 0 192.168.2.125:53 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named
tcp 0 0 172.17.0.1:53 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named
tcp 0 0 192.168.125.1:53 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named
tcp 0 0 192.168.0.200:53 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3125 -> /usr/sbin/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 30845 -> /usr/sbin/cupsd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3884 -> /usr/sbin/exim4
tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN 3055 -> /usr/sbin/named
tcp 0 0 0.0.0.0:32765 0.0.0.0:* LISTEN 3014 -> /sbin/rpc.statd
tcp 0 0 0.0.0.0:8895 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java
tcp 0 0 0.0.0.0:23423 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java
tcp 0 0 0.0.0.0:32767 0.0.0.0:* LISTEN 3827 -> /usr/sbin/rpc.mountd
tcp 0 0 0.0.0.0:23424 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java
tcp 0 0 0.0.0.0:32768 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:23523 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java
tcp 0 0 0.0.0.0:23524 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java
tcp 0 0 192.168.0.200:44331 0.0.0.0:* LISTEN 4078 -> /home/cv/jdk1.8.0_31/bin/java
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 3002 -> /sbin/rpcbind
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 4007 -> /usr/sbin/apache2
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN 3908 -> /usr/bin/Xorg:0
您可以围绕类似的行编写自己的包装器并将其添加到您的工具箱中!
答案3
只是为了好玩我做了这个:
sudo netstat -putan | awk '/master/ {out=""; for(i=1;i<=6;i++){out=out" "$i}; split($7,result,"/"); system("ps aux | grep -v grep | grep " result[1] " >> x&"); getline < "x"; print out " " $14}'
我想这就是你想要的。您始终可以将其用作别名,以简化其使用。
解释:
下一行获取 netstat 的输出并进行过滤master
sudo netstat -putan | awk '/master/
下一行存储 netstat 的输出。
out=""; for(i=1;i<=6;i++){out=out" "$i}
下一行获取 pid:
split($7,result,"/")
下一行从 ps aux 获取全名并打印所有内容
system("ps aux | grep -v grep | grep " result[1] " >> x&"); getline < "x";
最后打印出来:
print out " " $14
答案4
与 @iñaki-murillo 类似的解决方案,但使用/proc/pid/cmdline
而不是ps
and grep
。我还使用$NF
并假设最后一个字段是pid/procname
格式化的,而不是假设它是 7 美元(在我的系统上实际上是 6 美元)。
netstat -putan|awk '/master/ {split($NF, pid,"/");sub(FS $NF,x);getline cmd < ("/proc/"pid[1]"/cmdline");print $0" "pid[1]"/"cmd}'
解释
/master/
过滤包含 master 的行。
split($NF, pid,"/");
拆分最后一个字段/
并存储在pid
sub(FS $NF,x);
删除最后一个字段。
getline cmd < ("/proc/"pid[1]"/cmdline")
读取相关 pid 的命令行调用并将其保存在cmd
.
print $0" "pid[1]"/"cmd
全部打印出来