#!/bin/sh ## ## SCRIPT NAME: get_cpu_usage_info.sh ## ## PURPOSE: ## This script gets 'user', 'nice', 'system', and 'idle' CPU-data ## (in 'jiffies' --- typically hundredths of a second)) via output ## from the command 'cat /proc/stat'. ## ## This shell script is meant to be capable of returning info of 3 types: ## 1) a report of the usage of ALL the CPU's known to '/proc/stat' ## 2) a list of the CPU's --- for example, cpu, cpu0, cpu1, ... ## 3) 'user', 'nice', 'system', and 'idle' data for a user-specified CPU. ## ## This script takes a single parameter --- a text string --- to indicate ## which of these 3 types of info to return: ## 1) 'all' ## 2) 'cpuslist' ## 3) the name of a cpu, such as 'cpu0' or 'cpu1' --- or simply 'cpu' ## which represents all the CPU's. ## ## Example output from the 'cat /proc/stat' command: ## ## cpu 39842 1406 12184 1523220 6634 95 1824 0 0 ## cpu0 18990 914 4855 758670 3358 40 54 0 0 ## cpu1 20852 492 7329 764549 3275 54 1770 0 0 ## intr 872783 276605 3275 0 0 0 0 0 0 1 25293 0 0 ... about 300 more integers ## ctxt 1582873 ## btime 1385094848 ## processes 2593 ## procs_running 2 ## procs_blocked 0 ## softirq 567280 0 343218 2282 831 26582 7400 120750 119 66098 ## ######################################### ## EXPLANATION OF 'cat /proc/stat' OUTPUT: ## ## According to http://www.linuxhowtos.org/System/procstat.htm, ## the lines above can be described as follows. ## ## The very first "cpu" line aggregates the numbers in all of ## the other "cpuN" lines. ## ## These numbers identify the amount of time the CPU has spent ## performing different kinds of work. Time units are in USER_HZ ## or Jiffies (typically hundredths of a second). ## ## (The jiffie numbers reported in file /proc/stat are aggregates ## since the system first booted. Hence to get the values over ## a time interval, one should get the difference of values ## at a pair of start and end times.) ## ## The meanings of the columns are explained in 'man proc' --- ## specifically, the section on '/proc/stat'. The integers in the ## columns are 'jiffies' for columns, from left to right: ## ## 1 * user: normal processes executing in user mode ## 2 * nice: niced processes executing in user mode ## 3 * system: processes executing in kernel mode ## 4 * idle: twiddling thumbs ## After Linux 2.6.x kernels: ## 5 * iowait: waiting for I/O to complete ## 6 * irq: servicing interrupts ## 7 * softirq: servicing softirqs ## 8 * steal_time: the ticks spent in other operating systems when ## running in a virtualized environment like Xen - since the ## 2.6.11 Linux kernel ## 9 * guest: for time spent running a virtual CPU for guest operating ## systems under the control of the Linux kernel - since the ## 2.6.24 Linux kernel ## ## The "intr" line gives counts of interrupts serviced since boot time, ## for each of the possible system interrupts. The first column is ## the total of all interrupts serviced; each subsequent column is ## the total for that particular interrupt. ## ## The "ctxt" line gives the total number of context switches ## across all CPUs. ## ## The "btime" line gives the time at which the system booted, ## in seconds since the Unix epoch. ## ## The "processes" line gives the number of processes and threads ## created, which includes (but is not limited to) those created by ## calls to the fork() and clone() system calls. ## ## The "procs_running" line gives the number of processes currently ## running on CPUs. ## ## The "procs_blocked" line gives the number of processes currently ## blocked, waiting for I/O to complete. ## ########################################## ## THE 3 FUNCTIONS OF THIS SCRIPT: ## ## 1) ## If 'all' is passed, all the cpu-lines data from the 'cat /proc/stat' ## command is used. It is reformatted from 'jiffies' into percents in ## 'user', 'nice', 'system', and 'idle' columns. ## The reformatted columnar data is returned by this script --- ## to stdout (standard-out). ## ## 2) ## If 'cpuslist' is passed, a list of the CPU's is passed. Here is an ## how the list is created, using 'grep' and 'awk': ## ## $ cat /proc/stat | grep '^cpu' | awk '{print $1}' ## cpu ## cpu0 ## cpu1 ## ## ## The list is returned to stdout. ## ## 3) ## If a cpu-name is passed (like 'cpu0' or 'cpu1' or 'cpu'), ## the user-nice-system-idle-etc 'jiffies' data is returned. Example: ## A line like ## ## cpu0 18990 914 4855 758670 3358 40 54 0 0 ## ## may be returned to stdout. ## ##+######### ## CALLED BY: a Tk GUI script that shows CPU usage data as PERCENT-used ## needle readings on one or more meters (dials) drawn on a ## Tk canvas --- Tk script name: ## meters_cpu_usage.tk ## ## The 'all' output is intended to be used to show usage for ALL the CPU's ## in a text-window of the Tk script GUI. ## ## The 'cpuslist' output is intended to be used to show a list of ALL the ## CPU names. ## ##+################### ## MAINTENANCE HISTORY: ## Updated by: Blaise Montandon 2013nov21 Started this script on Linux, ## using Ubuntu 9.10 (2009 October, ## 'Karmic Koala'). ## Updated by: Blaise Montandon 2013dec04 Prep the 'awk' program for the ## 'all' input parameter. ## Updated by: Blaise Montandon 2013dec21 Added a '%idle' column, for each ## CPU in the report. ##+######################################################################### ## FOR TESTING: (show statements as they execute) # set -x ## Simply exit if there is no argument passed to this script. if test "$1" = "" then exit fi ##+############################################################# ## THE FOLLOWING IS EXECUTED IF $1 CONTAINS 'cpuslist'. ## ## The output goes to standard-out. ## ##+############################################################ if test "$1" = "cpuslist" then cat /proc/stat | grep '^cpu' | awk '{print $1}' exit fi ## END OF if test "$1" = "cpuslist" SECTION. if test "$1" = "all" then ########################################################################## ## SET REPORT HEADING. ########################################################################## HOST_ID="`hostname`" echo "\ ......................... `date '+%Y %b %d %a %T%p %Z'` ........................ CPU USAGE for CPU(s) ON HOST *** $HOST_ID *** If there is more than one CPU, the data for individual CPU's is labelled 'cpu0', 'cpu1', ... The totals (summed data) for ALL the CPU's is labelled 'cpu'. CPU USAGE is presented in clock 'ticks' --- sometimes called 'jiffies' which are on the order of 1/100th of a second. 5 6 0 1 2 3 4 Activity Total *PERCENT* *PERCENT* CPU User Nice System Idle Total ticks CPU-USAGE CPU-IDLE ID ticks ticks ticks ticks (1+2+3) (1+2+3+4) (100 * 5 / 6) (100 * 4 / 6) ------ ------ ----- ------- ------- --------- --------- ------------- ------------- " ########################################################################## ## Get the CPU data lines from file '/proc/stat' --- all lines that start ## with 'cpu'. Get the data twice, separated by about 0.5 or 1 second. ########################################################################## CPUdata1="`cat /proc/stat | grep '^cpu'`" SECONDS=3 # SECONDS=1 sleep $SECONDS CPUdata2="`cat /proc/stat | grep '^cpu'`" ########################################################################## ## Concatenate the two sets of data together and pipe the data into ## 'sort', and then into an 'awk' program to get the difference ## data --- the difference of user-nice-system-idle-etc 'jiffies' ## for each CPU --- and format the report lines. ########################################################################## ## SAMPLE CALCULATION: ## ## If the information for a cpu is displayed like this: ## ## cpu 607557 143290 385125 136873807 1279793 18764 14856 0 0 ## ## To get the average system load over any given amount of time, ## from the FIRST data sample, ## we read only the first four values into variables (for example, ## let us call them u1, n1, s1, and i1). ## ## Then we read the values from the SECOND data sample into ## new variables, u2, n2, s2, and i2. ## ## The total usage time is equal to ## ## (u2-u1) + (n2 - n1) + (s2 - s1). ## ## The total time overall is the usage time + (i2-i1). ## ## Take (100*usage)/total to get the percent-CPU-usage. ## ## If there are multiple CPU's, also get the percent-CPU-usage for ## 'cpu0', 'cpu1', ... ## ## ----------------------------- ## Similar /proc/stat info is at: ## http://juliano.info/en/Blog:Memory_Leak/Understanding_the_Linux_load_average ## http://www.linuxhowtos.org/System/procstat.htm ## http://stackoverflow.com/questions/5514119/accurately-calculating-cpu-utilization-in-linux-using-proc-stat ## http://askubuntu.com/questions/120953/exact-field-meaning-of-proc-stat ## http://man7.org/linux/man-pages/man5/proc.5.html ## http://stackoverflow.com/questions/1420426/calculating-cpu-usage-of-a-process-in-linux ############################################################################ CPUdata="$CPUdata1 $CPUdata2" echo "$CPUdata" | sort | awk '{ cpuid1=$1 u1=$2 n1=$3 s1=$4 i1=$5 getline cpuid2=$1 u2=$2 n2=$3 s2=$4 i2=$5 du=u2 - u1 dn=n2 - n1 ds=s2 - s1 di=i2 - i1 act=du + dn + ds tot=act + di pcentu=100 * act / tot pcenti=100 * di / tot printf("%-6s %7d %6d %7d %8d %10d %10d %11.2f %11.2f\n",cpuid2,du,dn,ds,di,act,tot,pcentu,pcenti) }' ## END of awk program ########################################################################## ## ADD REPORT 'TRAILER'. ########################################################################## SCRIPT_BASENAME=`basename $0` SCRIPT_DIRNAME=`dirname $0` echo " ......................... `date '+%Y %b %d %a %T%p %Z'` ........................ The output above is from script $SCRIPT_BASENAME in directory $SCRIPT_DIRNAME This script ran the command 'cat /proc/stat' twice ($SECONDS SECONDS APART) and used the 'user', 'nice', 'system', and 'idle' data for each CPU on host $HOST_ID to formulate the report. The script concatenates the lines of CPU data from the two data-samples, sorts the lines by CPU using the 'sort' command, and pipes the sorted data (2 lines for each CPU) into an 'awk' program. For the 2 lines of data for each CPU, the 'awk' program gets the difference of the 'user', 'nice', 'system', and 'idle' data and calculates the PERCENT-CPU-USAGE as indicated in the column headings above. ......................... `date '+%Y %b %d %a %T%p %Z'` ........................ " exit fi ## END OF if test "$1" = "all" SECTION. ##+############################################################# ## THE FOLLOWING IS EXECUTED IF $1 CONTAINS ANYTHING other than, ## 'all' or 'cpuslist'. It is assumed that $1 contains a CPU ## name such as 'cpu0' or 'cpu1' or 'cpu'. ## ## The output goes to standard-out. ## ## EXAMPLE OUTPUT FROM THE 'PIPE' BELOW, for 'cpu0': ## ## cpu0 18990 914 4855 758670 3358 40 54 0 0 ## ##+############################################################# cat /proc/stat | grep "$1" | head -1