ps(top) cheatsheet

下面这些操作平时可能不大会用到,但是关键时候却能大显身手,大部分跟 thead 有关。

展开 tid
htop -> F2
ps -p PID -L -o pid,tid,psr,pcpu


特定的 pid, tid 跑在哪些 core 上
1. top -H -p {PID} -> f -> j
2. /proc/{PID}/stat -> 第三列: running/stop,倒数第六列: core


通过 -o 指定需要获取的条目:
ps -eLf/ps aux -L
ps -eLo pid,ppid,lwp,nlwp,osz,rss,ruser,pcpu,stime,etime,args | more
ps -eLo pcpu,args | grep java | sort -k1 -r | awk '{print $1}' | head -n 1
ps ax –no-headings -o user,pid,%cpu,%mem,vsz,sgi_rss
ps axo "user=%u, pid=%p, command line args=%a, elapsed time=%t"
ps axo "Application: %c | CommandlineArgs: %a | PercentageCpu: %C | User: %U | VirtualMemory: %z" –sort vsize  | tail

上面的说了这么多,其实是为了解决下面这个问题,找出 java 中最耗 cpu 的 tid,jstack 追踪。要找出这 tid 方式也有很多种,top,ps 都可以实现。

top -H |head -n 10|grep java|awk '{print $1}'|head -n 1 |sed -r 's/[^0-9].*m//g'
主要注意的是 top -H 直接 grep 出来的有乱码,所以需要通过 sed 处理下,为了这个问题还花了点时间,最后把结果 pipe 到文件,vim 打开才发现了问题。

ps -eLo pcpu,args | grep java | sort -k1 -r | awk '{print $1}' | head -n 1
ps p {PID} -L -o time,pid,tid,pcpu,tname,stat,psr | sort -n -k1 –r
ps 做法会好的多处理起来也更漂亮。

ref:
http://stackoverflow.com/questions/1519196/finding-usage-of-resources-cpu-and-memory-by-threads-of-a-process-in-unix-sol
http://stackoverflow.com/questions/8032372/how-can-i-see-which-cpu-core-a-thread-is-running-in
http://stackoverflow.com/questions/3342889/how-to-measure-separate-cpu-core-usage-for-a-process
http://stackoverflow.com/questions/8032372/how-can-i-see-which-cpu-core-a-thread-is-running-in

使用 tr, rename, bash 内置变量修改文件名

有如下所示的目录,现要将目录中的 '-" 改成 "_"
$ ll
total 12
drwxrwxr-x 2 jaseywang jaseywang 4096 2012-07-29 15:09 1-2-3/
drwxrwxr-x 2 jaseywang jaseywang 4096 2012-07-29 15:09 4-5-6/
drwxrwxr-x 2 jaseywang jaseywang 4096 2012-07-29 15:09 7-8-9/

g 了如下几种方式,没找到源出处,侵权了可以联系我。

可以通过 tr 实现:
$ find . -type d -name "*-*" -print | while read name; do na=$(echo $name | tr '-' '_'); if [[ $name != $na ]]; then mv "$name" $na; fi; done
Continue reading

关于用户组的一些问题

新建一个用户组,指定 gid:
# addgroup --gid 3000 group1
# usermod -aG group1,group2,group3 user1

注意:-a 表示追加,如果没有的话,user1 的 group 就变成了 group1,group2,group3 了。

这个表示将 user1 的主用户组变成 www-data:
# usermod -g www-data user1

将一个用户加入到多个用户组中,这个解决的方式比较多,比如上面提到的方式。但是如果需要将将多个用户加到同一个用户组中,貌似没有现成的命令来解决,可以通过一个简单的脚本完成。
# cat users.txt
user1
user2
user3

# for users in $(cat users.txt)
do
    usermod -aG group_to_add $users
done

Ubuntu 修改时区

直接运行进去修改:
$ sudo dpkg-reconfigure tzdata

或者直接将需要的时区写进 timezone 文件,准确的时区去 /usr/share/zoneinfo/ 目录下找:
$ echo "Asia/Shanghai" | sudo tee /etc/timezone
$ sudo dpkg-reconfigure --frontend noninteractive tzdata

或者做软链接:
$ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

取代 netstat 的 ss

之前只知道有个 -s 能看到目前系统连接数的整体情况,实际上 ss 远比这个强大,远比 netstat 强大,最大的特点就是快。
$ ss -s

本地打开的端口:
$ ss -l
$ ss -ln
$ ss -lp

TCP,UDP,RAW,UNIX sockets:
$ ss -t -a
$ ss -u -a
$ ss -w -a
$ ss -x -a

如果某些协议修改了端口,要么要修改 services 对应的 port/service-name 要么就要直接使用数值的方式显示,比如我把 sshd 的端口修改成 11111:
$ ss -o state established '( dport = :11111 or sport = :11111 )' -p
Recv-Q Send-Q                                                                           Local Address:Port                                                                               Peer Address:Port  
0      256                                                                               11.11.111.21:11111                                                                           222.222.222.162:47868    timer:(on,207ms,0)
0      0                                                                                 11.11.111.21:11111                                                                           222.222.222.162:64872    timer:(keepalive,73min,0)
0      0                                                                                  192.18.10.15:11111                                                                               192.18.10.14:32984    timer:(keepalive,50min,0)

如果不修改 services 而直接使用的话,会找不到:
$ ss -o state established '( dport = :ssh or sport = :ssh )' -p
Recv-Q Send-Q                                                                           Local Address:Port                                                                               Peer Address:Port  
Continue reading

netstat 中的 Recv/Send

netstat 查看当前的连接情况,会出现 Recv-Q 以及 Send-Q 的这两栏:
Proto Recv-Q Send-Q Local Address           Foreign Address         State     
tcp        0    180 111.111.111.111:80      110.194.127.254:39922   FIN_WAIT1 
tcp        0      0 111.111.111.111:80      112.64.188.117:49319    TIME_WAIT 
tcp        0      0 111.111.111.111:80      221.131.128.207:61285   TIME_WAIT 
tcp        0    180 111.111.111.111:80      119.180.158.228:1131    FIN_WAIT1 
tcp        0      1 111.111.111.111:80      175.136.68.117:40492    LAST_ACK  
tcp        0    180 111.111.111.111:80      218.85.96.248:34279     FIN_WAIT1 
tcp        0      1 111.111.111.111:80      212.58.162.182:26196    FIN_WAIT1 
tcp        0      0 111.111.111.111:80      211.140.5.110:48673     TIME_WAIT 
tcp        0      1 111.111.111.111:80      117.136.11.171:46403    FIN_WAIT1

我理解的是,Recv 的是数据还在缓存中,还没被进程读取,这个值就是还没被进程读取的 bytes;而 Send 则是发送队列中没有被远程主机确认的 bytes 数。
这两个值正常情况下应该为0,暂时的不为 0 可以理解,但是长期的非 0 则表明出现了一些问题。如果 Recv 长期的不为 0,则表明可能遭受了 DOS 攻击或者说是程序有点问题,进程根本就没有读取缓存中的数据(?我个人猜测而已);而 Send 不为 0 则表示了,则表示本地发送的数据超出了对发的接受能力。

ref:
http://www.enterprisenetworkingplanet.com/netos/article.php/3430561/Keep-an-Eye-on-Your-Linux-Systems-with-Netstat.htm