I've been trying to get a one liner working updated to add the user name for the processes consuming swap on the system but having a hard time getting it to work.
The thread here gave me a pretty good script to work with and I've been partially successful but still seeing some issues.
for file in /proc/*/status ; do awk -F: '/Tgid|VmSwap|Name/{printf $2 }END{ print ""}' $file; done| grep kB | sort -k 3 -n -r | head -n 10 | awk 'BEGIN { ORS=" " };{print $0 system("ps -o user= -p " $2)}
The above produces the output:
username 0
processname0 1734 334248 kB0 username1
processname1 2314 182360 kB0 root
processname2 2069626 78292 kB0 username2
processname3 2069621 11500 kB0 root
processname4 2540 8720 kB0 root
processname5 1547 4320 kB0 root
processname6 1556 3380 kB0 root
processname7 2069656 3208 kB0 root
processname8 1398 1312 kB0 root
The username coming in a different line is an issue and the other one is the addition of the 0 after 'kB'.
I've tried a few different things but nothing seems to be working.
Also, the script is being run through another tool and has to be a one liner which is limiting the options a bit. Any help would be great.
After a lot more trial and error, I was able to get this working.
The following is the code snippet that ended up working:
for file in /proc/*/status ; do awk -F: '/Tgid|VmSwap|Name/{printf $2}END{print ""}' $file 2>/dev/null ; done | grep kB | sort -k 3 -n -r | head -n 10 | awk 'BEGIN{printf "%-20s %-10s %10s %-5s %10s\n","Process ID","PID","Size","Units","User"};{cmd="ps -o user= -p " $2; cmd | getline result; printf "%-20s %-10s %10s %-5s %10s\n",$1,$2,$3,$4,result}'
Related
I want to find out processes running more than 3 hrs, I have written a command for this but it's not returning expected output
ps -u <user> -o pid,stime,pcpu,pmem,etime,cmd --sort=start_time | \
grep <searchString> | grep -v grep| awk '{print $5}' | \
sed 's/:|-/ /g;'| awk '{print $4" "$3" "$2" "$1"}' | \
awk '$1+$2*60+$3*3600+$4*86400 > 10800'
but it's printing the values of etime in output. But expected output is, command should print the values of "pid,stime,pcpu,pmem,etime,cmd"
I am not able to find exact issue with this.
You are executing "awk '{print $5}'" which is taking in the input and printing out only column 5 which in your case is "etime" , everything from this point on is lost.
If your system supports etimes (notice the s on the end), you can easily do this with
ps -eo pid,etimes,etime,comm,user,tty | awk '{if ( $2>10800) print $0}'
on a system not supporting etimes which has a standard output of etime which hh:mm:ss or just mm:ss if no hours have passed
ps -eo pid,etime,comm,user,tty | awk '{seconds_old=10800 ; split($2,a,":",sep) ; if(length(a) < 3) b = (a[1] *60) + (a[2]) ; else b=((a[1]*3600) + (a[2] *60) + (a[3])) ; if(b > seconds_old ) print $0}'
Adjust "seconds_old" to change the age you want to test for:
There are various other methods of doing this using Find for example:
explained here:
https://serverfault.com/questions/181477/how-do-i-kill-processes-older-than-t
However, the solution should match your expected output
Try this:
ps -u <user> -o pid,stime,pcpu,pmem,etime=,cmd --sort=start_time|grep <searchString>|while read z;do tago=$(echo $z|awk '{print $5}'|sed -E 's/(:|-)/ /g'| awk '{print $4+$3*60+$2*3600+$1*86400}');if [ $tago -ge 10800 ];then echo $z;fi;done
It prints only processes >= 10800 secs old.
You can readjust the output further to fit your needs.
Able to find running process for more than 3 hrs with below command.
ps -u <user> -o pid,stime,pcpu,pmem,etime,cmd --sort=start_time |grep -v grep|awk 'substr($0,23,2) > 3'
Good day,
I need to add a Column header "TIME" that will display the current time for each time the output is executed on a new line with the following code:
top -b -n 1 -p 984 -o +PID -o +VIRT | sed -n '7,12p' | awk '{printf "%1s %-4s\n",$1,$5}'
Output I'm looking for:
TIME PID VIRT
12:00:00 984 1024
12:16:01 984 995
12:44:29 984 1008
(The values is only for display, not correct)
also it should be in a endless loop with interval of 10s until user stops it.
everything is executed from PIDandVIRT.sh
(Linux script)
Thank you for the help in advance
I would recommend to use the ps command instead of top:
echo "TIME PID VSIZE"
while true ; do
echo "$(date +%H:%I:%S) $(ps -p 984 -o pid,vsize --no-headers)"
sleep 1
done
Set an awk variable to the result of the date command:
awk -v time=$(date '+%H:%M:%S') '{printf "%s %1s %-4s\n", time, $1, $5}'
To get it in a loop, use while
while :; do
top -b -n 1 -p 984 -o +PID -o +VIRT | sed -n '7,12p' | awk -v time=$(date '+%H:%M:%S') '{printf "%s %1s %-4s\n", time, $1, $5}'
sleep 10
done
command who returns list of users logged to server
[admin#DB01ATK ~]$ who
adm_drodmann pts/3 2015-07-01 08:57 (10.129.12.77)
adm_ssmith pts/4 2015-07-01 02:11 (10.129.12.76)
adm_kholdman pts/2 2015-06-30 23:08 (10.129.12.45)
the point is to assign to variable, value of username($1) where terminal($2) is result from command
ps aux | grep screen
question asked question answered:
PTS=$(awk '{print $7}' <<< $(ps aux | grep screen) )
who | while read CMD;
do
res=$(awk '{print $2}' <<< "$CMD")
if [ "$res" = "$PTS" ]
then
echo "logged as $(awk '{print $1}' <<< "$CMD")"
fi
done;
:-)
As per your comment I expand my solution. You want to say:
ptw=$(ps aux | awk '/screen/ {print $7}')
while IFS=read -r user res _;
do
[ "$res" = "$PTS" ] && echo "logged as $user"
done < <(who)
When I am trying to run the below Script it says invalid option 3 for cat..Whats the problem?
I am tried to use index file which specifies which file is ham and which is spam...to read the files and train spamfilter
#!bin/bash
DirBogoDict=$1
BogoFilter=/home/gunna/Downloads/bogofilter-1.2.4/src/bogofilter
x=0
for i in 'cat index | fgrep spam | head -300 | awk -F "/" '{print$2"/"$3}''
do
x=$((x+1)) ; echo $x
cat /home/gunna/Downloads/db-6.1.19.NC/build_unix/ceas08-1/$i| $BogoFilter -d $DirBogoDict -M -k 1024 -s
done
for i in 'cat index | fgrep ham | head -300 | awk -F "/" '{print$2"/"$3}''
do
x=$((x+1)) ; echo $x
cat /home/gunna/Downloads/db-6.1.19.NC/build_unix/ceas08-1/$i | $BogoFilter -d $DirBogoDict -M -k 1024 -n
done
This part
'cat index | fgrep spam | head -300 | awk -F "/" '{print$2"/"$3}''
needs to be in back-ticks, not single quotes
`cat index | fgrep spam | head -300 | awk -F "/" '{print$2"/"$3}'`
And you could probably simplify it a little with
for i in `fgrep spam index | head -300 | awk "/" '{print$2"/"$3}'`
Kdopen has explained the error you got , here is the improved code for similar for-loop function.
DirBogoDict=$1
BogoFilter=/home/gunna/Downloads/bogofilter-1.2.4/src/bogofilter
awk '/spam/&&++myctr<=300{print $2 FS $3}' FS="/" index |while read i
do
cat /home/gunna/Downloads/db-6.1.19.NC/build_unix/ceas08-1/"$i"| $BogoFilter -d ${DirBogoDict} -M -k 1024 -s
done
awk '/ham/&&++myctr<=300{print $2 FS $3}' FS="/" index |while read i
do
cat /home/gunna/Downloads/db-6.1.19.NC/build_unix/ceas08-1/"$i"| $BogoFilter -d ${DirBogoDict} -M -k 1024 -s
done
Also look at your file names , since cat is giving an error and an option is invalid. To demonstrate this, Let say you have a file a name -3error
executing the following command
cat -3error
will gave
cat: invalid option -- '3'
cat therefore is thinking the "-" is followed by one of its command line arguments. As a result you probably get an invalid option error.
I have a bash script that is parsing files containing information about processes running on a server. Everything works except the output.
Target output
tomcat7 Running Monitored 3025 18d 2h 16m 3.6% 0.0%
What it actually is outputing
0.0%2h 16m ing
Script portion doing the parsing and output
for SERVER in $SERVERS ; do
SYSTEM=$(sed -n '/System/{p; n;p; n;p; n;p; n;p; n;p}' $H_DIR/$SERVER.txt)
sed -n '/Process/{p; n;p; n;p; n;p; n; n;p; n;n;n; n;p; n; n;p}' $H_DIR/$SERVER.txt > $H_DIR/procs.txt
split --lines=7 $H_DIR/procs.txt $H_DIR/procs.txt.
for PROC in $H_DIR/procs.txt.?? ; do
PROCESS=$(cat $PROC | head -1 | tail -1 | cut -d "'" -f2)
STATUS=$(cat $PROC | head -2 | tail -1 | awk '{ print $NF }')
MONITOR=$(cat $PROC | head -3 | tail -1 | awk '{ print $NF }')
PID=$(cat $PROC | head -4 | tail -1 | awk '{ print $NF }')
UPTIME=$(cat $PROC | head -5 | tail -1 | awk '{ print substr($0, index($0, $2)) }')
PCPU=$(cat $PROC | head -6 | tail -1 | awk '{ print $NF }')
PMEM=$(cat $PROC | head -7 | tail -1 | awk '{ print $NF }')
echo $PROCESS $STATUS $MONITOR $PID $UPTIME $PCPU $PMEM
done
rm -f $H_DIR/procs.*
rm -f $H_DIR/$SERVER.txt
done
raw file being parse
Process 'tomcat7'
status Running
monitoring status Monitored
pid 3025
uptime 18d 2h 30m
memory percent 3.6%
cpu percent 0.0%
On a hunch - your input files have the DOS carriage return line feed combination.
I added that to your file and got the same results you did.
See this question for how to remove the carriage return:
Remove carriage return in Unix
Using the suggested tr -d '\r' method for removing carriage return (and might as well remove single quotes at the same time) you could do something like this:
echo $(tr -d "\r\'" < $PROC | awk 'NR==5{print substr($0,index($0,$2))}{print $NF}')
or if you need each variable assigned then something like this
VARS=$(tr -d "\r\'" < $PROC | awk 'NR==5{print substr($0,index($0,$2))}{print $NF}')
read PROCESS STATUS MONITOR PID UPTIME PCPU PMEM <<<$VARS
echo $PROCESS $STATUS $MONITOR $PID $UPTIME $PCPU $PMEM
Either way, output is
tomcat7 Running Monitored 3025 18d 2h 30m 30m 3.6% 0.0%