getopt()用法详解 https://blog.csdn.net/qq_22642239/article/details/106462986

    1. #!/bin/bash
    2. # @Function
    3. # Find out the highest cpu consumed threads of java,and print the stack of these threads.
    4. #
    5. # @Usage
    6. # $ ./show-busy-java-threads.sh
    7. #
    8. # @author XieQing
    9. PROG=`basename $0`
    10. usage() {
    11. cat <EOF
    12. Usage: ${PROG} [OPTION]...
    13. Find out the highest cpu consumed threads of java,and print the stack of these threads.
    14. Example: ${PROG} -c 10
    15. Options:
    16. -p,--pid find out the highest cpu consumed threads from the specifed java process,default from all java process.
    17. -c,--count set the thread count to show,default is 5
    18. -h,--help display this help and exit
    19. EOF
    20. exit $1
    21. }
    22. ARGS=`getopt -n "$PROG" -a -o c:p:h -l count:,pid:,help -- "[email protected]"`
    23. [ $? -ne 0 ] && usage 1
    24. eval set -- "${ARGS}"
    25. while true; do
    26. case "$1" in
    27. -c|--count)
    28. count="$2"
    29. shift 2
    30. ;;
    31. -p|--pid)
    32. pid="$2"
    33. shift 2
    34. ;;
    35. -h|--help)
    36. usage
    37. ;;
    38. --)
    39. shift
    40. break
    41. ;;
    42. esac
    43. done
    44. count=${count:-5}
    45. redEcho() {
    46. [ -c /dev/stdout ] && {
    47. # if stdout is console,turn on color output.
    48. echo -ne "\033[1;31m"
    49. echo -n "[email protected]"
    50. echo -e "\033[0m"
    51. } || echo "[email protected]"
    52. }
    53. # Check the existence of jstack command!
    54. if ! which jstack &> /dev/null; then
    55. [ -z "$JAVA_HOME" ] && {
    56. redEcho "Error: jstack not found on PATH!"
    57. exit 1
    58. }
    59. ! [ -f "$JAVA_HOME/bin/jstack" ] && {
    60. redEcho "Error: jstack not found on PATH and $JAVA_HOME/bin/jstack file does NOT exists!"
    61. exit 1
    62. }
    63. ! [ -x "$JAVA_HOME/bin/jstack" ] && {
    64. redEcho "Error: jstack not found on PATH and $JAVA_HOME/bin/jstack is NOT executalbe!"
    65. exit 1
    66. }
    67. export PATH="$JAVA_HOME/bin:$PATH"
    68. fi
    69. uuid=`date +%s`_${RANDOM}_$$
    70. cleanupWhenExit() {
    71. rm /tmp/${uuid}_* &> /dev/null
    72. }
    73. trap "cleanupWhenExit" EXIT
    74. printStackOfThread() {
    75. while read threadLine ; do
    76. pid=`echo ${threadLine} | awk '{print $1}'`
    77. threadId=`echo ${threadLine} | awk '{print $2}'`
    78. threadId0x=`printf %x ${threadId}`
    79. user=`echo ${threadLine} | awk '{print $3}'`
    80. pcpu=`echo ${threadLine} | awk '{print $5}'`
    81. jstackFile=/tmp/${uuid}_${pid}
    82. [ ! -f "${jstackFile}" ] && {
    83. jstack ${pid} > ${jstackFile} || {
    84. redEcho "Fail to jstack java process ${pid}!"
    85. rm ${jstackFile}
    86. continue
    87. }
    88. }
    89. redEcho "Busy(${pcpu}%) thread(${threadId}/0x${threadId0x}) stack of java process(${pid}) under user(${user}):"
    90. sed "/nid=0x${threadId0x} /,/^$/p" -n ${jstackFile}
    91. done
    92. }
    93. ps -Leo pid,lwp,user,comm,pcpu --no-headers | {
    94. [ -z "${pid}" ] &&
    95. awk '$4=="java"{print $0}' ||
    96. awk -v "pid=${pid}" '$1==pid,$4=="java"{print $0}'
    97. } | sort -k5 -r -n | head --lines "${count}" | printStackOfThread