原文地址:
1 一些方便系统诊断的bash函数:http://hongjiang.info/common-bash-functions/ 2 3 这段脚本包含100多个bash函数,是我几年前方便自己调试和诊断问题写的。贴出来给有需要的人,因为比较懒怎么使用这些函数就不写说明了。其中以下划线开头的是表示私有函数,以cf_开头的表示公共函数,可当做命令使用。 4 # check current os is linux 5 function cf_is_linux() { 6 [[ "$OSTYPE" = *linux* ]] && echo "true" && return 0 7 echo "false" && return 1 8 } 9 10 # check current os is mac/darwin 11 function cf_is_darwin() { 12 [[ "$OSTYPE" = *darwin* ]] && echo "true" && return 0 13 echo "false" && return 1 14 } 15 16 # check current os is windows/cygwin 17 function cf_is_cygwin() { 18 [[ "$OSTYPE" = *cygwin* ]] && echo "true" && return 0 19 echo "false" && return 1 20 } 21 22 function cf_is_gnu_date() { 23 date --version >/dev/null 2>&1 && echo "true" && return 0 24 echo "false" && return 1 25 } 26 27 function cf_is_gnu_sed() { 28 sed --version >/dev/null 2>&1 && echo "true" && return 0 29 echo "false" && return 1 30 } 31 32 function cf_is_gnu_awk() { 33 awk --version | grep GNU >/dev/null && echo "true" && return 0 34 echo "false" && return 1 35 } 36 37 function cf_is_gnu_grep() { 38 grep --version | grep GNU >/dev/null && echo "true" && return 0 39 echo "false" && return 1 40 } 41 42 # java style startsWith 43 function cf_starts_with() { 44 local str=$1 45 local pre=$2 46 [[ "$str" == ${pre}* ]] 47 } 48 49 # java style substring 50 function cf_substring() { 51 local str=$1 52 local begin=$2 53 local end=$3 54 if [ -z "$end" ]; then 55 echo ${str:$begin} 56 else 57 local len=`expr $end - $begin` 58 echo ${str:$begin:$len} 59 fi 60 } 61 62 # get current shell name 63 function cf_shell_name() { 64 local name=$( ps -ocommand= -p $$ | awk '{print $1}') 65 if cf_starts_with $name "-"; then 66 cf_substring $name 1 67 else 68 echo $name 69 fi 70 } 71 72 # check current shell is bash 73 function cf_is_bash() { 74 [[ `cf_shell_name` = "-bash" || `basename $(cf_shell_name)` = "bash" ]] && echo "true" && return 0 75 echo "false" && return 1 76 } 77 78 # check current shell is zsh 79 function cf_is_zsh() { 80 [[ `cf_shell_name` = "-zsh" || `basename $(cf_shell_name)` = "zsh" ]] && echo "true" && return 0 81 echo "false" && return 1 82 } 83 84 function _script_dir() { 85 if cf_is_bash >/dev/null; then 86 cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd -P 87 elif cf_is_zsh >/dev/null; then 88 cd "$( dirname "${(%):-%N}" )" && pwd -P 89 else 90 echo "unsupported shell" && return 1 91 fi 92 } 93 94 function _script_file() { 95 if cf_is_bash >/dev/null; then 96 basename "${BASH_SOURCE[0]}" 97 elif cf_is_zsh >/dev/null; then 98 basename "${(%):-%N}" 99 else100 echo "unsupported shell" && return 1101 fi102 }103 104 # colorful grep. private function105 function _get_colorful_grep() {106 cf_is_gnu_grep >/dev/null && echo "grep --color" && return 0107 export GREP_OPTIONS='--color=always'108 export GREP_COLOR='1;35;40'109 echo "grep" 110 }111 112 # list all common functions113 function cf_functions() {114 if cf_is_bash >/dev/null; then115 declare -F | awk '{print $NF}' | grep "cf_" | sort116 elif cf_is_zsh >/dev/null; then117 print -l ${(ok)functions} | grep "cf_" | sort118 else119 echo "unsupported shell" && return 1120 fi121 }122 123 # get total memory (MB)124 function cf_mem_total() {125 if cf_is_linux >/dev/null; then126 free -m | awk '/^Mem/{print $2"M"}'127 elif cf_is_darwin >/dev/null; then128 sysctl hw.memsize | awk '{print $2/1024/1024"M"}'129 else130 echo "unsupported os" && return 1131 fi 132 }133 134 # decimal to hexadecimal135 function cf_dec2Hex() {136 printf "%x" $1137 }138 139 # decimal to octal 140 function cf_dec2Oct() {141 printf "%o" $1142 }143 144 # decimal to binary145 function cf_dec2Bin() {146 echo "obase=2; $1" | bc147 }148 149 # hexadecimal to decimal 150 function cf_hex2Dec() {151 echo $((16#$1))152 }153 154 # octal to decimal 155 function cf_oct2Dec() {156 echo $((8#$1))157 }158 159 # binary to decimal 160 function cf_bin2Dec() {161 echo $((2#$1))162 }163 164 function cf_calc() {165 local exp="$1"166 echo "$exp" | bc -l | awk '{printf "%.2f", $0}'167 }168 169 # warning and exit, not for interactive shell170 function cf_die() {171 local msg="$1"172 local code=${ 2:-1}173 echo "$msg" && exit $code174 }175 176 # highlight key words from file or pipeline177 function cf_highlight() {178 local keyword="$1"179 local cgrep="$(_get_colorful_grep)"180 if [ -p /dev/stdin ]; then181 # from pipeline182 while IFS='' read line; do183 echo $line | eval "$cgrep -E \"${keyword}|$\""184 done185 else186 local file="$2"187 eval "$cgrep -E \"${keyword}|$\"" "$file"188 fi189 }190 191 function cf_ps_env() {192 local pid=$1193 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1194 195 if cf_is_linux >/dev/null; then196 xargs --null --max-args=1 < /proc/$pid/environ197 elif cf_is_darwin >/dev/null; then198 ps -wwE -p $pid199 else200 echo "unsupported os" && return 1201 fi202 }203 204 # get bash(current shell) major version205 function cf_bash_major_ver() {206 echo ${BASH_VERSINFO[0]}207 }208 209 # get bash(current shell) minor version210 function cf_bash_minor_ver() {211 echo ${BASH_VERSINFO[1]}212 }213 214 # get kernel version215 function cf_kernel_ver() {216 if cf_is_linux >/dev/null; then217 uname -r | cut -d'-' -f1218 elif cf_is_darwin >/dev/null; then219 uname -r | cut -d'-' -f1220 else221 echo "unsupported os" && return 1222 fi223 }224 225 # get kernel major version226 function cf_kernel_major_ver() {227 if cf_is_linux >/dev/null; then228 uname -r | awk -F'.' '{print $1"."$2}' 229 elif cf_is_darwin >/dev/null; then230 uname -r | awk -F'.' '{print $1"."$2}' 231 else232 echo "unsupported os" && return 1233 fi234 }235 236 # get kernel minor version237 function cf_kernel_minor_ver() {238 if cf_is_linux >/dev/null; then239 uname -r | awk -F'.' '{print $3}'240 elif cf_is_darwin >/dev/null; then241 uname -r | awk -F'.' '{print $3}'242 else243 echo "unsupported os" && return 1244 fi245 }246 247 # get value from config file such as app.properties248 function cf_get_property() {249 local file="$1"250 local key="$2"251 grep "^${key}=" "$file" | tr -d '\r' | cut -d'=' -f2 | cf_trim252 }253 254 # get command path, eg: `cf_command_path ls` output /usr/bin/ls255 function cf_command_path() {256 local cmd=$1257 cf_is_bash && builtin type -P $cmd && return $?258 259 if [ -x /usr/bin/which ]; then260 local p=$( /usr/bin/which $1 | head -1 )261 [ ! -z "$p" ] && echo $p && return 0262 return 1263 else264 local p=$( which $1 | grep "^/" | head -1 )265 [ ! -z "$p" ] && echo $p && return 0266 return 1267 fi268 }269 270 # get all ip addresses271 function cf_ip_list() {272 if [ -x /sbin/ip ]; then273 local list=$(/sbin/ip -o -4 addr list | awk '{print $4}' | cut -d'/' -f1 | tr '\n' ',')274 else275 local list=$(/sbin/ifconfig | grep "inet " | awk '{print $2}' | sed 's/addr://' | tr '\n' ',')276 fi277 echo ${list%,}278 }279 280 function cf_stdio() {281 local pid=$1282 /usr/sbin/lsof -a -p $pid -d 0,1,2283 }284 285 function cf_stdout() {286 local pid=$1287 if cf_is_linux >/dev/null; then288 readlink -f /proc/$pid/fd/1289 elif cf_is_darwin >/dev/null; then290 /usr/sbin/lsof -a -p $pid -d 1 | awk 'NR>1{print $NF}'291 else292 echo "unsupported os" && return 1293 fi294 }295 296 # get file last modification time297 function cf_last_modification() {298 local file="$1"299 if [[ $OSTYPE == *linux* ]];then300 date +%Y%m%d%H%M%S -r $file301 elif [[ $OSTYPE == *darwin* ]];then302 stat -f "%Sm" -t "%Y%m%d%H%M%S" $file303 fi304 }305 306 # check current user is root 307 function cf_is_root() {308 [ `whoami` = "root" ] && echo "true" && return 0309 echo "false" && return 1310 }311 312 # check current shell is interactive313 function cf_is_interactive_shell() {314 if cf_is_bash >/dev/null; then315 [[ "$-" = *i* ]] && echo "true" && return 0316 elif cf_is_zsh >/dev/null; then317 [[ -o interactive ]] && echo "true" && return 0318 else319 echo "unsupported shell" && return 1320 fi321 echo "false" && return 1322 }323 324 # check current shell is login shell325 function cf_is_login_shell() {326 if cf_is_bash >/dev/null; then327 shopt -q login_shell && echo "true" && return 0328 elif cf_is_zsh >/dev/null; then329 [[ -o login ]] && echo "true" && return 0330 else331 echo "unsupported shell" && return 1332 fi333 echo "false" && return 1334 }335 336 # check command is exists337 function cf_is_command_exists() {338 local cmd=$1339 if [ -x /usr/bin/which ]; then340 /usr/bin/which $cmd >/dev/null 2>&1 && echo "true" && return 0341 else342 which $cmd >/dev/null 2>&1 && echo "true" && return 0 343 fi344 echo "false" && return 1345 }346 347 # check file name globbing flag348 function cf_is_glob_enabled() {349 if cf_is_bash >/dev/null; then 350 [[ $- != *f* ]] && echo "true" && return 0351 elif cf_is_zsh >/dev/null; then352 [[ -o glob ]] && echo "true" && return 0353 else354 echo "unsupported shell" && return 1355 fi356 echo "false" && return 1357 }358 359 # enable file name globbing360 function cf_enable_glob() {361 cf_is_bash >/dev/null && set +f && return 0362 cf_is_zsh >/dev/null && set -o glob && return 0363 echo "unsupported shell" && return 1364 }365 366 # disable file name globbing367 function cf_disable_glob() {368 cf_is_bash >/dev/null && set -f && return 0369 cf_is_zsh >/dev/null && set -o noglob && return 0370 echo "unsupported shell" && return 1371 }372 373 # check extglob flag374 function cf_is_extglob_enabled() {375 if cf_is_bash >/dev/null; then 376 shopt -q extglob && echo "true" && return 0377 elif cf_is_zsh >/dev/null; then378 [[ -o kshglob ]] && echo "true" && return 0379 else380 echo "unsupported shell" && return 1381 fi382 echo "false" && return 1383 }384 385 # enable extglob 386 function cf_enable_extglob() {387 cf_is_bash >/dev/null && shopt -s extglob && return 0388 cf_is_zsh >/dev/null && set -o kshglob && return 0389 echo "unsupported shell" && return 1390 }391 392 # disable extglob 393 function cf_disable_extglob() {394 cf_is_bash >/dev/null && shopt -u extglob && return 0395 cf_is_zsh >/dev/null && unsetopt kshglob && return 0396 echo "unsupported shell" && return 1397 }398 399 # check pid is exists400 function cf_is_pid_exists() {401 local pid=$1402 [ -z "$pid" ] && echo "false" && return 1403 kill -0 $pid >/dev/null 2>&1 && echo "true" && return 0404 echo "false" && return 1405 }406 407 function cf_is_java() {408 local pid=$1409 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1410 ps -ocommand= -p$pid | awk '$1~/java$/' > /dev/null && echo "true" && return 0411 echo "false" && return 1412 }413 414 function cf_is_available_port() {415 local port=$1416 if [[ "$OSTYPE" = *linux* ]];then417 local r=$( netstat -ant | awk '$6=="LISTEN" && $4~":'$port'$"' )418 elif [[ "$OSTYPE" = *darwin* ]];then419 local r=$( netstat -ant | awk '$6=="LISTEN"' | grep "\.$port " )420 else421 echo "unknown system" && return 1422 fi423 424 [ -z "$r" ] && echo "true" && return 0;425 echo "false" && return 1 # port has been used426 }427 428 function cf_defined() {429 if cf_is_bash >/dev/null; then430 [[ ${!1-X} == ${!1-Y} ]]431 elif cf_is_zsh >/dev/null; then432 [[ ${(P)1-X} == ${(P)1-Y} ]]433 else434 echo "unsupported shell" && return 1435 fi436 }437 438 function cf_has_value() {439 cf_defined $1 || return 1440 if cf_is_bash >/dev/null; then441 [[ -n ${!1} ]] && return 0442 elif cf_is_zsh >/dev/null; then443 [[ -n ${(P)1} ]] && return 0444 fi445 return 1446 }447 448 function cf_has_sudo_privilege() {449 # do not need password450 sudo -n echo >/dev/null 2>&1451 }452 453 function cf_timestamp() {454 date +%F-%T | tr ':-' '_' #2015_12_01_22_15_22455 }456 457 function cf_length() {458 echo ${#1}459 }460 461 # trim string462 function cf_trim() {463 if [ -p /dev/stdin ]; then464 while IFS='' read line; do465 _trim "$line"466 done467 else468 _trim "$1"469 fi470 }471 472 # private function473 function _trim() {474 local str="$1"475 local extglob=$(cf_is_extglob_enabled)476 if cf_is_bash >/dev/null || cf_is_zsh >/dev/null; then477 [ $extglob = "false" ] && cf_enable_extglob478 str="${str##*( )}"479 str="${str%%*( )}"480 [ $extglob = "false" ] && cf_disable_extglob481 else482 echo "unsupported shell" && return 1483 fi484 echo $str485 }486 487 function cf_lower() {488 echo "$1" | tr '[:upper:]' '[:lower:]'489 }490 491 function cf_upper() {492 echo "$1" | tr '[:lower:]' '[:upper:]'493 }494 495 function cf_ps_name() {496 local pid=$1497 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1498 if cf_is_java $pid >/dev/null; then499 local main=$(cf_ps_java_main $pid)500 echo "java($main)"501 else502 ps -ocommand= -p $pid | awk '{print $1}'503 fi504 }505 506 function cf_ppid() {507 local pid=$1508 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1509 ps -oppid= -p $pid510 }511 512 function cf_ps_java_main() {513 local pid=$1514 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1515 ps -ocommand= -p $pid | tr ' ' '\n' | awk '/-classpath|-cp/{getline;next};/^-/{next}1' | awk 'NR==2'516 }517 518 function cf_ps_time() {519 local pid=$1520 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1521 522 local elapsed="$(ps -oetime= -p $pid | cf_trim)"523 local started="$(ps -olstart= -p $pid | cf_trim)"524 if [ `cf_is_gnu_date` = "true" ]; then525 started=$(date +'%Y-%m-%d %H:%M:%S' -d "$started")526 fi527 local cpu_time=$(ps -otime= -p $pid | cf_trim)528 echo "started from: $started, elapsed: $elapsed, cumulative cpu time: $cpu_time"529 }530 531 function cf_ps_zombies() {532 ps -opid,state,command -e | awk 'NR==1 || $2=="Z"'533 }534 535 function cf_connection_topology() {536 local pid=$1537 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1538 539 /usr/sbin/lsof -Pan -iTCP -p $pid > /tmp/.$pid.lsof540 grep -o "[0-9.:]*->[0-9.:]*" /tmp/.$pid.lsof > /tmp/.$pid.conns541 grep "LISTEN" /tmp/.$pid.lsof | awk '$9~/*/{print substr($9,3)}' > /tmp/.$pid.ports542 543 echo "-------------- downstream -------------"544 for port in $(cat /tmp/.$pid.ports); do545 cf_connection_list_by_port $port | awk '$6=="ESTABLISHED" {print $5}' | cut -d':' -f1 | sort | uniq -c | awk '{print $2"-->localhost:"'$port'" ("$1")"}'546 done547 548 echo "-------------- upstream ---------------"549 local portsExpr=$(cat /tmp/.$pid.ports | sed -e 's/^/:/' -e 's/$/->/' | xargs | sed 's/ /|/g')550 grep -Ev "$portsExpr" /tmp/.$pid.conns > /tmp/.$pid.out551 awk -F'->' '{print $2}' /tmp/.$pid.out | sort | uniq -c | sort -nrk1 | awk '{print "localhost-->"$2" ("$1")"}'552 rm -f /tmp/.$pid.lsof /tmp/.$pid.conns /tmp/.$pid.ports553 }554 555 function cf_connection_list_by_pid() {556 local pid=$1557 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1558 /usr/sbin/lsof -Pan -iTCP -p $pid559 }560 561 function cf_connection_list_by_port() {562 local port=$1563 netstat -ant| awk '$4~/[:.]'"$port"'$/'564 }565 566 function cf_connection_stat_by_pid() {567 local pid=$1568 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1569 local interval=${ 2:-1}570 /usr/sbin/lsof -Pan -iTCP -p $pid -r $interval571 }572 573 function cf_connection_stat_by_port() {574 local port=$1575 netstat -ant -c| awk '$1=="Proto"{print "\n"$0};$4~/[:.]'"$port"'$/'576 }577 578 function cf_listening_sockets() {579 #lsof -Pnl -i4TCP -sTCP:LISTEN #low version unsupported -sTCP params580 if cf_is_linux >/dev/null || cf_is_darwin >/dev/null; then581 if cf_has_sudo_privilege; then582 sudo /usr/sbin/lsof -Pnl -i4TCP | grep LISTEN583 else584 /usr/sbin/lsof -Pnl -i4TCP | grep LISTEN585 fi586 else587 netstat -plnt 2>/dev/null | grep -v tcp6588 fi589 }590 591 function cf_traffic_by_eth() {592 local eth=${ 1:-"eth0"}593 if cf_is_linux >/dev/null; then594 [ ! -d /sys/class/net/$eth ] && echo "network interface not exists." && return 1595 while true; do596 local r1=`cat /sys/class/net/$eth/statistics/rx_bytes`597 local t1=`cat /sys/class/net/$eth/statistics/tx_bytes`598 sleep 1599 local r2=`cat /sys/class/net/$eth/statistics/rx_bytes`600 local t2=`cat /sys/class/net/$eth/statistics/tx_bytes`601 local rkbps=`cf_calc "( $r2 - $r1 ) / 1024"`602 local tkbps=`cf_calc "( $t2 - $t1 ) / 1024"`603 echo "$eth: RX $rkbps kB/s TX $tkbps kB/s"604 done605 elif cf_is_darwin >/dev/null; then606 # `netstat -I eth0 -w 1` or `nettop -n -m tcp`607 declare -a tuple608 local _i1=0609 cf_is_zsh >/dev/null && _i1=1610 local _i2=1611 cf_is_zsh >/dev/null && _i1=2612 while true; do613 tuple=( $(netstat -nbi -I $eth | tail -1 | awk '{print $7,$10}') )614 local r1=${tuple[$_i1]}615 local t1=${tuple[$_i2]}616 sleep 1617 tuple=( $(netstat -nbi -I $eth | tail -1 | awk '{print $7,$10}') )618 local r2=${tuple[$_i1]}619 local t2=${tuple[$_i2]}620 local rkbps=`cf_calc "( $r2 - $r1 ) / 1024"`621 local tkbps=`cf_calc "( $t2 - $t1 ) / 1024"`622 echo "$eth: RX $rkbps kB/s TX $tkbps kB/s"623 done624 else625 echo "unsupported os" && return 1626 fi627 }628 629 function cf_traffic_by_pid() {630 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1631 local pid=$1632 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1633 634 # kernel 2.6.18 not support, must 2.6.32 or later?635 local pf="/proc/$pid/net/netstat"636 [ ! -f $pf ] && echo "$pf not found!" && return 1637 638 declare -a tuple639 local _i1=0640 cf_is_zsh >/dev/null && _i1=1641 local _i2=1642 cf_is_zsh >/dev/null && _i1=2643 local pname="$(cf_ps_name $pid)"644 while true; do645 tuple=( $(grep "IpExt: " $pf | awk 'NR==2{print $8,$9}') )646 local r1=${tuple[$_i1]}647 local t1=${tuple[$_i2]}648 sleep 1649 tuple=( $(grep "IpExt: " $pf | awk 'NR==2{print $8,$9}') )650 local r2=${tuple[$_i1]}651 local t2=${tuple[$_i2]}652 local rkbps=`cf_calc "( $r2 - $r1 ) / 1024"`653 local tkbps=`cf_calc "( $t2 - $t1 ) / 1024"`654 echo "$pname: IN $rkbps kB/s OUT $tkbps kB/s"655 done656 }657 658 function cf_iotop() {659 sudo iotop -bod1660 }661 662 function cf_check_sum() {663 local dir=${ 1:-$PWD}664 local dirsum=0665 for sum in $(find ${ dir} -type f -print0 | xargs -0 cksum | awk '{print $1}')666 do667 dirsum=$(( ${ sum} + ${dirsum} ))668 done669 echo ${dirsum}670 }671 672 function cf_java_classpath_check() {673 [ $# -eq 0 ] && echo "please enter classpath dir" && return 1674 [ ! -d "$1" ] && echo "not a directory" && return 1675 676 local tmpfile="/tmp/.cp$(date +%s)"677 local tmphash="/tmp/.hash$(date +%s)"678 local verbose="/tmp/cp-verbose.log"679 680 if cf_is_zsh >/dev/null;then681 local -a files682 local begin=1683 elif cf_is_bash >/dev/null;then684 declare -a files685 local begin=0686 else 687 echo "unsupported shell" && return 1688 fi689 files=(`find "$1" -name "*.jar"`)690 691 for f in $files; do692 jarName=`basename $f`693 list=`unzip -l $f | awk -v fn=$jarName '/\.class$/{print $NF,fn}'`694 size=`echo "$list" | wc -l`695 echo $jarName $size >> $tmphash696 echo "$list"697 done | sort | awk 'NF{ a[$1]++;m[$1]=m[$1]","$2}END{for(i in a) if(a[i] > 1) print i,substr(m[i],2)}' > $tmpfile698 699 awk '{print $2}' $tmpfile | awk -F',' '{i=1;for(;i<=NF;i++) for(j=i+1;j<=NF;j++) print $i,$j}' | sort | uniq -c | sort -nrk1 | 700 while read line; do701 local dup=${line%% *}702 local jars=${line#* }703 local jar1=${jars% *}704 local jar2=${jars#* }705 local len_jar1=`grep -F "$jar1" $tmphash | grep ^"$jar1" | awk '{print $2}'`706 local len_jar2=`grep -F "$jar2" $tmphash | grep ^"$jar2" | awk '{print $2}'`707 local len=$(($len_jar1 > $len_jar2 ? $len_jar1 : $len_jar2))708 local per=$(echo "scale=2; $dup/$len" | bc -l)709 echo ${per/./} $dup $jar1 $jar2710 done | sort -nr -k1 -k2 | awk 'NR==1{print "Similarity DuplicateClasses File1 File2"}{print "%"$0}'| column -t711 712 sort $tmpfile | awk '{print $1,"\n\t\t",$2}' > $verbose713 echo "See $verbose for more details."714 715 rm -f $tmpfile716 rm -f $tmphash717 }718 719 function cf_java_class_find() {720 local libdir=$1721 local name=$2722 local glob=$(cf_is_glob_enabled)723 [ $glob = "false" ] && cf_enable_glob724 builtin pushd $libdir >/dev/null725 for j in *.jar; do726 unzip -l $j | grep $name && echo $j;727 done728 builtin popd >/dev/null729 [ $glob = "false" ] && cf_disable_glob730 }731 732 function cf_java_pids() {733 ps x | grep "jav[a]" | awk '{print $1}'734 }735 736 function cf_java_infos() {737 for p in `cf_java_pids`; do738 echo "java pid: $p"739 info=`ps -opid=,command= -p $p | tr ' ' '\n' | awk '/-classpath|-cp/{getline;next};/-Xmx|-Dcatalina.base/{print};/^-/{next};1' | xargs`740 echo " $info"741 time=`cf_ps_time $p`742 echo " $time"743 done744 }745 746 function cf_java_threads() {747 local pid=$1748 local vm_threads="GC task|VM |CompilerThread|Finalizer|Reference Handler|Signal Dispatcher"749 "$JAVA_HOME"/bin/jstack $pid | grep "^\"" | grep -Ev "$vm_threads"750 }751 752 function cf_java_sysprops() {753 local pid=$1754 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1755 "$JAVA_HOME"/bin/jinfo -sysprops $pid756 }757 758 function cf_jstack_series() {759 local pid=$1760 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1761 local count=${ 2:-5} # defaults 5 times762 local delay=${ 3:-0.5} # defaults 0.5 seconds763 764 local logdir=${LOG_DIR:-"/tmp"}765 while [ $count -gt 0 ]; do766 if cf_is_gnu_date >/dev/null; then 767 local suffix=$(date +%H%M%S.%N)768 else769 local suffix=$(date +%H%M%S)"."$count770 fi771 "$JAVA_HOME"/bin/jstack $pid > $logdir/jstack.$pid.$suffix772 sleep $delay773 let count--774 echo -n "."775 done776 }777 778 function cf_dmesg() {779 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1780 781 dmesg -T "$@" 2>/dev/null782 [ $? -eq 0 ] && return 0783 784 dmesg "$@" | perl -w -e 'use strict;785 my ($uptime) = do { local @ARGV="/proc/uptime";<>}; ($uptime) = ($uptime =~ /^(\d+)\./);786 foreach my $line (<>) {787 printf( ($line=~/^\[\s*(\d+)\.\d+\](.+)/) ? ( "[%s]%s\n", scalar localtime(time - $uptime + $1), $2 ) : $line )788 }'789 }790 791 function cf_trace_http_request() {792 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1793 local pid=$1794 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1795 strace -e read -s 2000 -qftp $pid 2>&1 | grep " HTTP/1[.][01][\]r[\]n" 796 }797 798 function cf_trace_http_response() {799 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1800 local pid=$1801 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1802 strace -e write -s 2000 -qftp $pid 2>&1 | grep "HTTP/1[.][01] " 803 }804 805 function cf_trace_http_req_header() {806 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1807 local pid=$1808 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1809 strace -e read -s 2000 -qftp $pid 2>&1 | grep " HTTP/1[.][01][\]r[\]n" | sed 's/\\r\\n/\n/g'810 }811 812 function cf_trace_http_resp_header() {813 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1814 local pid=$1815 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1816 strace -e write -s 2000 -qftp $pid 2>&1 | grep "HTTP/1[.][01] " | sed 's/\\r\\n/\n/g'817 }818 819 function cf_trace_http_invoke() {820 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1821 local pid=$1822 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1823 strace -e sendto -s 2000 -qftp $pid 2>&1 | grep " HTTP/1[.][01][\]r[\]n" 824 }825 826 function cf_trace_connect() {827 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1828 local pid=$1829 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1830 strace -e connect -s 2000 -qftp $pid 2>&1 | grep "port"831 }832 833 function cf_trace_socket() {834 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1835 local pid=$1836 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1837 strace -e connect,socket,close -s 2000 -qftp $pid 2>&1 | grep "port"838 }839 840 function cf_trace_sql_select() {841 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1842 local pid=$1843 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1844 strace -e sendto,write -s 2000 -qftp $pid 2>&1 | grep -i "[\]3select"845 }846 847 function cf_trace_sql_update() {848 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1849 local pid=$1850 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1851 strace -e sendto,write -s 2000 -qftp $pid 2>&1 | grep -i "[\]3update"852 }853 854 function cf_trace_sql_insert() {855 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1856 local pid=$1857 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1858 strace -e sendto,write -s 2000 -qftp $pid 2>&1 | grep -i "[\]3insert"859 }860 861 function cf_trace_redis_command() {862 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1863 local pid=$1864 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1865 local cmd=$2866 strace -e sendto,write -s 2000 -qftp $pid 2>&1 | grep -i "$cmd[\]r[\]n"867 }868 869 function cf_trace_dubbo_request() {870 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1871 local pid=$1872 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1873 strace -e read -s 2000 -qftp $pid 2>&1 | grep -i "[\]tinterface"874 }875 876 function cf_trace_dubbo_invoke() {877 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1878 local pid=$1879 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1880 strace -e write -s 2000 -qftp $pid 2>&1 | grep -i "[\]tinterface"881 }882 883 function cf_trace_system_call() {884 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1885 local pid=$1886 ! cf_is_pid_exists >/dev/null $pid && echo "pid:$pid not exists" && return 1887 local time=${ 2:-5}888 889 local outfile="/tmp/.sys-call.$pid"890 strace -cqftp $pid -o $outfile & 891 local spid=$!892 while [ $time -gt 0 ]; do893 sleep 1894 let time--895 echo -n "."896 done897 echo ""898 kill $spid && echo "ok"899 # if strace process still exists900 cf_is_pid_exists $spid >/dev/null 2>&1 && kill -9 $spid901 cat $outfile && rm -f $outfile902 }903 904 function cf_random_entropy_stat() {905 ! cf_is_linux >/dev/null && echo "only works in linux" && return 1906 while true; do907 echo "entropy available:" `cat /proc/sys/kernel/random/entropy_avail`908 sleep 1909 done910 }911 912 function cf_json_fmt() {913 python -mjson.tool914 }915 916 function cf_http_server() {917 local port=${ 1:-8000}918 python -mSimpleHTTPServer $port 2>/dev/null919 }