I need to write a Bash script that does the following:
Example: Assuming that there are three "chrome" processes, the output in "logfile" should look something like below (for the first three seconds):
17:49:12 7954 14.0
17:49:12 7969 9.3
17:49:12 2626 1.3
17:49:13 7954 12.0
17:49:13 7969 6.3
17:49:13 2626 1.2
17:49:14 7954 14.7
17:49:14 7969 8.5
17:49:14 2626 2.1
My ideas so far: Using the command
top -b -n 1 -p 7954 | tail -n 2 | head -n 2 | awk '{print $1, $9}' >> logfile
I filter top by PID (in this case PID == 7954) and the output looks like
PID %CPU
7954 6.6
however (since I actually want to filer by COMMAND) I do not know how to filter by COMMAND. In the line above, the "-p 7954" does the filtering for PID==7954, however what do I need to write here to filter by COMMAND==chrome? Also, How can I remove/avoid the header?
According to the time step: I found that the command
date +"%T"
gives me the time in the correct format (hh:mm:ss).
So I just struggle with putting these pieces together and fix the filtering problem mentioned above. Thank you for any help!
Awk can do this; awk '/regex/ { print }'
performs the print
action only on lines matching regex
.
However, you can (and perhaps also should) subsume head
and tail
as well:
top -b -n 1 | awk 'NR>1 && $10 == "chrome" {print strftime("%T"), $1, $9}'
... assuming the tenth field of top
output contains the command name.
however what do I need to write here to filter by COMMAND==chrome
Write a small script to accomplish this, say calc_proc_mem
which looks like below :
#!/bin/bash
if [ -z "$1" ] #checking if first param exist
then
echo "Usage : cal_proc_mem process_name"
exit 1 # Exiting with a non-zero value
else
proc_ids=( $(pgrep "$1") )
if [ ${#proc_ids[@]} -eq 0 ] #checking if if pgrep returned nothing
then
echo "$1 : Process Not Running/No such process"
exit 1 # Exiting with a non-zero value
else
echo "$1's %CPU-%MEM usage as on $(date +%F)" >> logfile
while true
do
for proc_id in "${proc_ids[@]}"
do
usage="$(ps -p "$proc_id" -o %cpu,%mem | awk -v pid=$proc_id 'NR==2{printf "PID : %-10d \%CPU : %f \%MEM : %f\n",pid,$1,$2}' 2>/dev/null)"
echo -e "$(date +%H:%M:%S)\t$usage" >> logfile
done
sleep 3
done
fi
fi
Run the script as
./calc_proc_mem process_name
Sample Output
chrome's %CPU-%MEM usage as on 2016-06-27
23:40:33 PID : 3983 %CPU : 1.300000 %MEM : 2.200000
23:40:33 PID : 8448 %CPU : 0.100000 %MEM : 4.300000
23:40:33 PID : 8464 %CPU : 0.000000 %MEM : 0.400000
23:40:33 PID : 8470 %CPU : 0.000000 %MEM : 0.200000
23:40:33 PID : 8526 %CPU : 0.000000 %MEM : 3.000000
23:40:33 PID : 8529 %CPU : 0.000000 %MEM : 0.200000
23:40:33 PID : 8563 %CPU : 0.000000 %MEM : 1.500000
23:40:33 PID : 8655 %CPU : 0.300000 %MEM : 4.900000
23:40:33 PID : 32450 %CPU : 0.300000 %MEM : 2.100000
Note
Since you've an infinite while-loop
running, you need to manually terminate the program using Ctrl C.
You can drop '-p PID' option and next, grep by COMMAND. You can do the next:
top -b -n 1 | grep 'chrome' | tail -n 2 | head -n 2 | awk '{print $1, $9}'
Another command sample to get you going could be:
$ cmd="sleep"; for j in {1..3}; do (${cmd} 123 &); done;
$ ts=$(date +"%T"); top -b -n 1| sed s/^[^\ 0123456789].*$//g |grep "${cmd}"|tr -s '\n'| awk '{print $1, $9, $12}'|sed s/^/"${ts} "/g
19:36:51 35122 0.0 sleep
19:36:51 35124 0.0 sleep
19:36:51 35126 0.0 sleep
It prints the time as given by the date call, and from top: PID, %CPU, and COMMAND field found. The headers and non matching data lines are filtered via sed (no number at start, which could suppress small pids by the way =( thus also a space at line start is accepted) and grep on the command. The time is prepended py sed on start of line injecting the stored timestamp and a blank space to separate.
It is not elegant but might fit your needs to have a start.
The pgrep solutions or using awk with a regex look better ... but at least I enjoyed trying to solve it with top. The tail and head stages in the pipe look suspicious to me ...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.