How to get Memory Usage for a PID in a variable using bash - bash

This is what I've been working with but haven't been successful,
if [ "$memUsage" -gt "30500" ];
then
transUsage=$(pmap 3097 | tail -n 1 | awk '/[0-9]/{print $2}')
transUsage=$transUsage | awk '/[0-9]/{print $2}' #This was my attempt at removing the extra K
if [ "$transUsage" -gt "10500" ];
then
echo "Terminated this and this"
fi
# Print the usage
echo "Memory Usage: $memUsage KB"
fi
I need memory usage of PID 3097 in variable so that I could use if command.
Currently it outputs,
xxxxK, where x is memory usage size. Due to K being part of size, it's not being being recognized as numeric value.
How to solve this? Would appreciate the help.
Regards!

You can use this better code:
#!/bin/bash
pid=$1
transUsage=$(pmap $pid | awk 'END{sub(/K/, "", $2); print $2}')
if ((transUsage > 10500)); then
echo "Terminated this and this"
fi
echo "Memory Usage: $transUsage KB"
((...)) is an arithmetic command, which returns an exit status of 0 if the expression is nonzero, or 1 if the expression is zero. Also used as a synonym for "let", if side effects (assignments) are needed. See http://mywiki.wooledge.org/ArithmeticExpression.

Related

Bash single-line nested for-loop is taking comparison variable as a command

I believe my error is in do if ($i -gt 100) area but I havent been able to figure it out.
My input is:
for i in `ps | cut -d ' ' -f1`; do if ($i -gt 100); then echo $i; fi; done
My output is this where the process IDs have been taken as commands.
bash: 13968: command not found
bash: 21732: command not found
bash: 21733: command not found
bash: 21734: command not found
How can I fix this and what is the relevant man page that I should read up on? Thank you.
if ($i -gt 100)
should be changed to
if [ $i -gt 100 ]
Note that there is a space before and after [], this is neccessary, otherwise you will get a syntax error (its because [ is a link to test in /usr/bin).
The relevant manapge would be man test, as [ is test.
Also, but this has nothing to do with the question, I recommend switchting from
`command`
to
$(command)
in bash.
It's not clear what your script is trying to do (the posted answers produce no output on my system) but if you want to print all PIDs that are greater than 100, here's how you'd do that:
$ ps | awk '$1 > 100{print $1}'
PID
314024
217880
230804
217084
263048
260788
218016
313464
201556
200732
just add spaces after and before brackets and the expression
for i in `ps | cut -d ' ' -f1`; do if [ $i -gt 100 ]; then echo $i; fi; done

Compare length of sound file in bash

I want to have a shell script, that checks the length of a sound file and check if the length is shorter, than a specified length. But I keep getting an error message "command not found" at the if-statement.
#!/bin/bash
soundlength=$(soxi -D $1)
enter code here
if [$soundlength < $2]
then
# do something
fi
I am guessing the $soundlength is a string and it's failing to compare string to int, but I can't find a solution to this.
Thanks in advance for all answers.
The problem is that soxi returns 0 or a float - example 27.741995, therefore you will need bc or awk to check if the output is bigger than N, this because bash don't support floats.
Here is an example with bc:
#!/bin/bash
soundlength=$(soxi -D $1)
if [ 1 -eq "$(echo "${soundlength} > ${2}" | bc)" ]; then
echo "${soundlength} is > than ${2}"
fi
And here is an example with AWK:
#!/bin/bash
soundlength=$(soxi -D $1)
if awk 'BEGIN{exit ARGV[1]>ARGV[2]}' "$z" "$y"; then
echo "${soundlength} is > than ${2}"
fi
If you don't want to use either bc of awk you could give a try to zsh shell, it supports floats.

Screen-saver inhibit script

I would like to automatize screen-saver inhibit, when using Firefox's "plugin-container" for flash player in KDE4. I did not write the original script myself, but I fixed it a bit.
#!/bin/sh
# Simple script to demonstrate D-Bus usage
while true
do
# read firefox plugin-container cpu usage
ret=$(top -b -n1 -u "$(whoami)" | gawk '$12 ~ /plugin-containe/ { SUM += $9 }; END { print SUM }')
if [ -n "$ret" ] && [ "$ret" -gt 15 ]; then
idle_time=`qdbus org.kde.screensaver /ScreenSaver GetSessionIdleTime`
if [ "$idle_time" -gt 50 ]; then
qdbus org.kde.screensaver /ScreenSaver SimulateUserActivity
fi
fi
sleep 50
done
Now when I run the script i get this error:
/home/geo/bin/plugin-containe: line 7: [: 68.75: integer expression expected
I tried to get top to output integer number but I couldn’t.
What can I do to fix?
Regards
Georges
If the awk output is the cause of the non-integer value then you can use the awk int() function to truncate the value of SUM to an integer value (i.e. int(SUM)).

Bash Script Loop Out of Memory?

In bash I need to run a script that loops from i=1 to i=99999999 but it always run out of memory. Is there any workaround? or is there a max value for i?
first=1
last=99999999
randomString="CXCXQOOPSOIS"
for val in $( seq $first $last )
do
padVal=$( printf "%010d\n" $val )
hash=$( echo -n $randomString$padVal | md5sum )
if [[ "$hash" =~ ^000000) ]]; then
echo "Number: $val" >> log_000000
echo "$val added to log - please check."
fi
done
bash provides C-like syntax for loop:
first=1
last=99999999
randomString="CXCXQOOPSOIS"
for ((val=$first; val<$last; val++))
do
padVal=$( printf "%010d\n" $val )
hash=$( echo -n $randomString$padVal | md5sum )
if [[ "$hash" =~ ^000000) ]]; then
echo "Number: $val" >> log_000000
echo "$val added to log - please check."
fi
done
Your seq command generates 100 million numbers (bar a couple) and requires 800 MiB or so of memory to hold just the list of digits (probably an under-estimate; each number might be held in a separate memory allocation, which might mean 8 bytes for a pointer and 16 bytes for the allocated block, which triples the storage space estimate).
You can improve things dramatically by using:
for millions in $(seq 0 99)
do
for smallstuff in $(seq -f "%6.0f" 0 999999)
do
val="$millions$smallstuff"
...
done
done
This dramatically reduces the amount of memory needed; the only issue to watch is that it tests 0 which your original code did not.
If you still want to use seq => therefore separate seq and the loop using a pipe: |
This solution is more portable and can be used on other shells.
The memory print is still reduced, but this script requires to process two threads.
first=1
last=99999999
randomString="CXCXQOOPSOIS"
seq $first $last |
while read val
do
padVal=$( printf "%010d\n" $val )
hash=$( echo -n $randomString$padVal | md5sum )
if [[ "$hash" =~ ^000000) ]]; then
echo "Number: $val" >> log_000000
echo "$val added to log - please check."
fi
done

Trying to test space in filesystem on Unix

I need to check if I Filesystem exists, and if it does exist there is 300 MB of space in it.
What I have so far:
if [ "$(df -m /opt/IBM | grep -vE '^Filesystem' | awk '{print ($3)}')" < "300" ]
then
echo "not enough space in the target filesystem"
exit 1
fi
This throws an error. I don't really know what I'm doing in shell.
My highest priority is AIX but I'm trying to get it to work for HP and Sun too.
Please help.
-Alex
Here is the code I got working.
if [ "$(df -m /opt/IBM/ITM | awk 'NR==2{print ($3)}')" -lt "300" ]
then
echo "not enough space in the target filesystem"
exit 1
fi
How about posting the error? Anyway, try the following syntax, ie. double brackets and no double quotes:
if [[ $(...) < 300 ]]; then
...
fi
From man bash:
[[ expression ]]
Return a status of 0 or 1 depending on the evaluation of the conditional
expression expression.

Resources