How to display processes that are using memory in an given range - linux

How can I display processes that are using memory between an given interval in terminal? For exemple: processes that are using between 50 and 100 MB of Memory.
I tried:
ps aux | awk '{print $4}' | sort
but this only displays the memory for every process sorted and not in an interval.

This will list processes as expected. Remember that ps shows memory size in kilobytes.
ps -u 1000 -o pid,user,stime,rss \
| awk '{if($4 > 50000 && $4 < 100000){ print $0 }}' \
| sort -n -k 4,4
Command output:
3407 luis.mu+ 10:30 51824
3523 luis.mu+ 10:30 66108
3410 luis.mu+ 10:30 71060
3595 luis.mu+ 10:30 74340
3609 luis.mu+ 10:30 77772
18550 luis.mu+ 16:47 93616
In that case it's showing only 4 fields for user id 1000. To show all processes use
ps -e -o pid,user,stime,rss
From the ps(3) man page under STANDARD FORMAT SPECIFIERS:
rss
resident set size, the non-swapped physical memory that a task has used (inkiloBytes)
If you want to show more fields, check the man page and add fields to -o option.

For more complex testing, including comparison, inequality, and numerical tests, awk is very useful:
ps aux | awk '{print $4}' | sort | awk '$1 >= 1 && $1 <=2'| cat
Here I am checking the memory usage between 1MB and 2MB using awk and printing them using cat.

Related

use 'grep' command the way column names would be preserved

I paid attention that 'grep' command removes the column names.
I need to customize the output of processes according to the following command:
ps -ef | egrep "java|mysql" | awk {'print $1, $2, $8'}
Regular 'ps' (or even with the 'awk') have column names: UID, PID, etc...
However, when i add 'grep' the column names gone.
Ideally i must have the 'ps' output that displays 4 columns - PID, user name, CMD, and memory usage.
How do i get it preserving the column names.
The grep command will strip the headers because they do not match. Just use awk and match on the first row condition in addition to the search patterns.
ps -ef | awk 'NR==1{print $1,$2,$8} /java|mysql/{print $1, $2, $8}'
Use the power of bash.
$ cat pid_top.sh
#!/bin/bash
echo "Enter String:"
read p
top -n 1 -b -p $(ps -e | grep $p | awk '{print $1}') | tail -n 2
Don't forget chmod +x pid_top.sh
Make an alias or run the script by name, enter a string, e.g. for firefox just fire an you will have and output like this:
$ ./p*
Enter String:
fire
PID USER PR NI VIRT RES SHR S %CPU %MEM ZEIT+ BEFEHL
2983 bang 20 0 1605624 600168 108940 S 0,0 15,1 40:28.10 firefox

How to get Network Traffic as one number on Linux

currently I am using this script to get CPU Load, Memory Load and used Diskspace. Now I want to expand it to also give me Network traffic.
top -bn1 | grep "Cpu(s)" | \
sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | \
awk '{print "CPU Load> " 100 - $1"%"}'
free | grep Mem | awk '{print "Memory Usage> "$3/$2 * 100.0"%"}'
used=$(df / | awk 'END{print $5}')
echo "Storage Used> "$used
The result should look something like this:
CPU Load> 82.8%
Memory Usage> 98.7924%
Storage Used> 23%
Network Traffic> 281 byte/s
Is there some way to go about that?
Sorry, I missed the bottom of your comment where you are looking for throughput. in this case, I'd use ifstat
apt-get install ifstat.
And in your script.
ifstat 1 1 | tail -1 | awk '{ print $1,$2}'.
this will give you Kb in and out. you can add them together.

Get CPU and Memory Info In Different HPUX unix Servers

I am trying to make a bash script to get CPU and Memory information in different Unix servers and pipe them into a single text file in the local server.
The script returns something (result), but the result was not accurate when I check each of the servers CPU and Memory information manually. There might be some error in the scripts since the CPU and Memory commands are correct.
Here is the command to get CPU information in Unix (HPUX) :
machinfo | grep CPUs | awk '{print $5}'
And the result will be :
4
And here is the command to get Memory information in Unix (HPUX) :
machinfo | grep Memory | awk '{print $3}'
And the result will be :
4090
It shows that the commands are correct. Let's go into the full scripts.
#!/bin/ksh
SERVERS='
xxx.xxx.xxx.xxx
xxx.xxx.xxx.xxx'
cpu=$(machinfo | grep CPUs | awk '{print $5}')
mem=$(machinfo | grep Memory | awk '{print $3}')
print "SERVER" "CPU" "RAM (MB)";
for i in $SERVERS
do
ssh -n $i 2>&1 '$cpu | $mem'
print $cpu $mem
done
When the full scripts run, the result will be:
SERVER CPU RAM (MB)
s24bf011 2 4090
s24bf012 2 4090
s24bf013 2 4090
s24bf014 2 4090
s24bf016 2 4090
S24BF104 2 4090
S24BF105 2 4090
10.14.24.158 2 4090
S29BF200 2 4090
S02BF131 2 4090
S02BF104 2 4090
S24BF071 2 4090
S24BF165 2 4090
10.14.24.17 2 4090
Every server has a different CPU and RAM. How come they were all the same?
Error in SSHing?
Your script has multiple problems.
'$cpu | $mem'
is just a literal string. If you want to interpolate the values of $cpu and $mem, you need to use double quotes instead of single.
But
"$cpu | $mem"
will basically discard the output from $cpu because you are piping it to $mem which is ignoring its standard input. The proper way to run two independent commands is to put a semicolon between them, not a pipe. The function of the pipe is to take the standard output from the command before the pipe and redirect it as standard input into the command after the pipe.
But of course, the variables you declared do not contain the scripts; they contain the output of the Awk scripts, which you ran locally when you put them in process substitutions.
You should have received error messages about all of this; what happened to them?
Anyway, you can simplify processing enormously by refactoring this to just run a single command, anyway.
print "SERVER" "CPU" "RAM (MB)";
for i in $SERVERS
do
ssh -n "$i" "machinfo |
awk -v s='$i' '/CPUs/ { c=\$5 } /Memory/ { m=\$3 }
END { print s, c, m }'"
done
Here, I use double quotes around the remote command so that I can interpolate the server name into the Awk variable s. The internal single quotes inside the double quotes do not have any significance to the local shell, i.e. they do not prevent the local shell from replacing the dollar signs, so we need to protect the dollar signs by backslash-escaping them.
But unless your local Awk is crippled or something, it doesn't make sense to run Awk remotely.
for i in $SERVERS
do
ssh -n "$i" machinfo |
awk -v s="$i" '/CPUs/ { c=$5 } /Memory/ { m=$3 }
END { print s, c, m }'
done
Putting stuff which isn't variable and which is only used once into a variable is just silly, and sometimes problematic (see http://mywiki.wooledge.org/BashFAQ/050).

The number of processes a user is running using bash

I would like to know how I could get the number of processes for each user that is currently logged in.
You could try some variation of this:
ps haux Ou | cut '-d ' -f1 | uniq -c
It gives you the number of processes for each users (being logged in or not). Now you could filter those results using the output of the w command or another way of determining who is logged in.
Give this a try:
ps -u "$(echo $(w -h | cut -d ' ' -f1 | sort -u))" o user= | sort | uniq -c | sort -rn
In order to properly handle usernames that may be longer than eight characters, use users instead of w. The latter truncates usernames.
ps -u "$(echo $(printf '%s\n' $(users) | sort -u))" o user= | sort | uniq -c | sort -rn
ps -u aboelnour | awk 'END {print NR}'
will show number of process which user aboelnour running it
If you are ever concerned about nearing the user process limit shown by ulimit -a, the you want to get ALL the processes (including LWPs). In such a case you should use:
ps h -Led -o user | sort | uniq -c | sort -n
On one system doing this:
ps haux Ou | cut '-d ' -f1 | uniq -c
yields:
# ps haux Ou | cut '-d ' -f1 | uniq -c
30 user1
1 dbus
3 user2
1 ntp
1 nut
1 polkitd
2 postfix
124 root
2 serv-bu+
where doing the former yields the true process count:
# ps h -Led -o user | sort | uniq -c | sort -n
1 ntp
1 nut
2 dbus
2 postfix
2 serv-builder
3 user2
6 polkitd
141 root
444 user1
Just try:
lslogins -o USER,PROC
If you just want a count of processes you can use procfs directly like this:
(requires linux 2.2 or greater)
you can use wc:
number_of_processes=`echo /proc/[0-9]* | wc -w`
or do it in pure bash (no external commands) like this
procs=( /proc/[0-9]* )
number_of_proccesses=${#procs[*]}
If you only want the current userid
procs=( /proc/[0-9]*/fd/. )
number_of_proccesses=${#procs[*]}
userlist=$(w|awk 'BEGIN{ORS=","}NR>2{print $1}'|sed 's/,$//' )
ps -u "$userlist"
Following links contain useful ps commands options including your requirements:
Displaying all processes owned by a specific user
Show All Running Processes in Linux
Here is my solution, for Linux:
$ find /proc –user $USER -maxdepth 1 -name '[0-9]*' | wc –l
This solution will not fail when the number of processes is larger than the command line limit.

How to get the total physical memory in Bash to assign it to a variable?

How can I get the total physical memory in bytes of my Linux PC?
I need to assign it to a bash script variable.
grep MemTotal /proc/meminfo | awk '{print $2}'
The returned number is in KB
phymem=$(awk -F":" '$1~/MemTotal/{print $2}' /proc/meminfo )
or using free
phymem=$(LANG=C free|awk '/^Mem:/{print $2}')
or using shell
#!/bin/bash
while IFS=":" read -r a b
do
case "$a" in
MemTotal*) phymem="$b"
esac
done <"/proc/meminfo"
echo $phymem
I came up with this one under the assumption, that the physical memory will be the first number in free's output:
free -m | grep -oP '\d+' | head -n 1
This allows you to configure free to output the unit you want (-m, -g, ...) and it is independent of the system language (other answers depend on the "Mem:" string in free's output which may change based on the language).
How about
var=$(free | awk '/^Mem:/{print $2}')
I'll try to make this answer self explanatory, just keep up with me.
To get the description of memory, you can use the free utility :
free -t
Output (in KB):
total used free shared buff/cache available
Mem: 8035900 3785568 324984 643936 3925348 3301908
Swap: 3906556 271872 3634684
Total: 11942456 4057440 3959668
To extract all of these values from this output in a single column :
free -t | grep -oP '\d+'
Output (in KB):
8035900
3866244
266928
650348
3902728
3214792
3906556
292608
3613948
11942456
4158852
3880876
Note : Minute difference can be there in values, which doesn't matter most of the times.
If you just want to get the total physical memory (mem+swap), it is the 10th value in above output :
free -t | grep -oP '\d+' | sed '10!d'
Output (on my PC):
11942456
Note: All the above outputs are in Kilo Bytes. If you want in Mega Bytes or Giga Bytes just append -m or -g after -t in
above free commands respectively.
For Example :
free -t -g | grep -oP '\d+' | sed '10!d'
Output (in Giga Bytes on my PC) :
11
Silly inline python version, which looks overly complicated, but is actually kind of useful.
freemem=$(echo -e 'import re\nmatched=re.search(r"^MemTotal:\s+(\d+)",open("/proc/meminfo").read())\nprint(int(matched.groups()[0])/(1024.**2))' | python)
It returns the memory in GB.
If someone need a human readable:
var=$(free -h | awk '/^Mem:/{print $2}')
result:
1.9G

Resources