LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-11-2008, 05:38 PM   #1
jhyland87
LQ Newbie
 
Registered: Dec 2008
Posts: 25

Rep: Reputation: 15
Bash Scripting Help?


Hey guys! How are you? Im a new member to Linux Questions, but not new to Linux, but.. new to bash scripting, lol.

I run a small hosting company, with a few clients, but the few clients that I do have, use all my CPU and MEM, thus I wanted to find a way to suspend them when they use too much. I made a custom script out of PHP, and its running as a cron on root permissions, but I just dont feel comfortable doing this with PHP. Its just... weird to me. Linux administration shouldn't be done with PHP.

Here is my PHP code to do what I am trying to do.

PHP Code:
function checkPs()
//==================================================================================
{
global 
$cpu_column;
global 
$usr_column;
global 
$mem_column;
global 
$pid_column;
global 
$cmd_column;

echo 
"Populating User List ..";
$usr shell_exec("ps aux |awk {'print $1'}");
$usr_column split("\n"$usr);
echo 
"                \033[32m[  OK  ]\033[30m\r\n";

echo 
"Populating CPU List ..";
$cpu shell_exec("ps aux |awk {'print $3'}");
$cpu_column split("\n"$cpu);
echo 
"                \033[32m[  OK  ]\033[30m\r\n";

echo 
"Populating MEM List ..";
$mem shell_exec("ps aux |awk {'print $4'}");
$mem_column split("\n"$mem);
echo 
"                \033[32m[  OK  ]\033[30m\r\n";

echo 
"Populating CMD List ..";
$cmd shell_exec("ps aux |awk {'print $11'}");
$cmd_column split("\n"$cmd);
echo 
"                \033[32m[  OK  ]\033[30m\r\n";

echo 
"Populating PID List ..";
$pid shell_exec("ps aux |awk {'print $2'}");
$pid_column split("\n"$pid);
echo 
"                \033[32m[  OK  ]\033[30m\r\n";

}
//================================================================================== 
What that does is get each column, and split it into lines, then split that into arrays, here is an example. of what it does, EXACTLY

Quote:
PID | User --- | Command | CPU | MEM
1 --| phrotect | php5 --- | 90% | 10%
2 --| clevel -- | crond -- | 85% | 15%
That would output the following
Quote:
$pid[1]=1; $user[1]=phprotect; $command[1]=php5;$cpu[1]=90; $mem[1]=10;
$pid[2]=2; $user[2]=clevel; $command[2]=crond; $cpu[2]=85; $mem[2]=15;
That way I can simply match the array key, and check the value of memory and cpu, if its over the limit, I get $user[$key] and run the suspend script.

However, How would I do such a thing in bash? I know I can split
ps aux |awk {'print $2'} into rows, but how would I grab the array key and make it suspend the user?

OR!
Do you think that PHP Is a perfectly fine way to run this, and that I shouldnt fix what isnt broken. I have ran this script on my server for some time, and have not had a single issue with it yet, and it has saved my butt a few times, users have gotten cron jobs up to 95%, and I kill the process and send them an email that there process was killing the CPU usage, and that the script was being executed at $time, using $memory, and was killed, and its all automated.

It even has a nice little CLI with it:
http://phprotect.com/images/CG-ss1.png
And its great at keeping logs:
http://phprotect.com/images/CG-ss2.png

I have big plans for this, and I know how to do it all in PHP, but if I want to either give it away, or sell it, I am not sure that people would want PHP running on Cron scripts to help the server.

WHat would you rather have?
1) Well coded PHP Script running on root level that works well on cron
2) Bash scripting on daemon
3) PHP script on daemon (Is that even possible?)

Thanks guys! Let me know what you think
 
Old 12-11-2008, 07:21 PM   #2
nathacof
Member
 
Registered: Aug 2004
Location: Bear, DE, USA
Distribution: Slackware 11, CentOS 5.2, Ubuntu
Posts: 124

Rep: Reputation: 17
Why fix what ain't broke? PHP is more advanced than Bash, and for your purposes it seems to fit.

Many web applications rely on PHP scripts that run via cron. Plesk to name one major Control Panel that I know of off the top of my skull. :P
 
Old 12-11-2008, 08:20 PM   #3
jhyland87
LQ Newbie
 
Registered: Dec 2008
Posts: 25

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by nathacof View Post
Why fix what ain't broke? PHP is more advanced than Bash, and for your purposes it seems to fit.

Many web applications rely on PHP scripts that run via cron. Plesk to name one major Control Panel that I know of off the top of my skull. :P
So you feel that php is perfectly fit for it?

The main reason I didnt want it was I thought.. wait, what if it turns into a big process on bigger servers, and kills php5 (its self).

..read up on it, PHP CLI uses no over head, and this script wont ever take longer than 2 seconds to execute.

Who else feels php is good for this?

And can I make it a daemon? Somehow....
 
Old 12-12-2008, 07:31 PM   #4
jhyland87
LQ Newbie
 
Registered: Dec 2008
Posts: 25

Original Poster
Rep: Reputation: 15
anyone got any ideas better than making this run as a cron?
 
Old 12-12-2008, 11:46 PM   #5
forrestt
Senior Member
 
Registered: Mar 2004
Location: Cary, NC, USA
Distribution: Fedora, Kubuntu, RedHat, CentOS, SuSe
Posts: 1,288

Rep: Reputation: 99
Not to be throwing a wet blanket on your party, but you really need to rethink the way you are doing this (not the php/bash issue) but you are running 5 different instances of ps. There is nothing saying that all the processes from the first instance will still be running during the 5th instance. Therefore the $pid[x] may REALLY belong to $cpu[x-1] and you are getting your statistics and killing the wrong process. Furthermore, you could be pointing to the wrong user as the offending cpu hog.

Here is a better script in bash (yes, you really should be doing this in bash as your php code is just calling bash shells which call ps and awk anyway).

Code:
#!/bin/bash

function checkPs() {

echo -n "Populating Lists .."

# Get all the pertinent data at once
PS=`ps aux | awk '{ print $1 "|" $3 "|"  $4 "|" $11 "|" $2 }'`

COUNT=0
for PROCESS in $PS ; do
        #This AWK command outputs a short bash "program" which can be called w/ eval to set the right variables 
        eval `echo $PROCESS | awk -F\| '{printf ("USR=%s;CPU=%s;MEM=%s;CMD=%s;PID=%s", $1, $2, $3, $4, $5)}'`
        
        #Now put the variables into arrays
        USRS[${COUNT}]=$USR
        CPUS[${COUNT}]=$CPU
        MEMS[${COUNT}]=$MEM
        CMDS[${COUNT}]=$CMD
        PIDS[${COUNT}]=$PID
        let COUNT=COUNT+1
done

echo -e "                \033[32m[  OK  ]\033[0m"

}

checkPs

# To access the array values do like the following
echo ${PIDS[50]} ${USRS[50]} ${CMDS[50]} ${CPUS[50]} ${MEMS[50]}
All this being said, if a process is taking up a lot of CPU usage, it doesn't necessarily need to be killed. Only if the server is being effected. If a process is running and no other processes need the CPU, it will take all the CPU it can get until it is done. You should only kill a high CPU using process if the system is actually being affected.

HTH

Forrest

Last edited by forrestt; 12-13-2008 at 12:15 AM. Reason: Changed list to lists in the first echo statement
 
Old 12-13-2008, 05:04 PM   #6
jhyland87
LQ Newbie
 
Registered: Dec 2008
Posts: 25

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by forrestt View Post
Not to be throwing a wet blanket on your party, but you really need to rethink the way you are doing this (not the php/bash issue) but you are running 5 different instances of ps. There is nothing saying that all the processes from the first instance will still be running during the 5th instance. Therefore the $pid[x] may REALLY belong to $cpu[x-1] and you are getting your statistics and killing the wrong process. Furthermore, you could be pointing to the wrong user as the offending cpu hog.

Here is a better script in bash (yes, you really should be doing this in bash as your php code is just calling bash shells which call ps and awk anyway).

Code:
#!/bin/bash

function checkPs() {

echo -n "Populating Lists .."

# Get all the pertinent data at once
PS=`ps aux | awk '{ print $1 "|" $3 "|"  $4 "|" $11 "|" $2 }'`

COUNT=0
for PROCESS in $PS ; do
        #This AWK command outputs a short bash "program" which can be called w/ eval to set the right variables 
        eval `echo $PROCESS | awk -F\| '{printf ("USR=%s;CPU=%s;MEM=%s;CMD=%s;PID=%s", $1, $2, $3, $4, $5)}'`
        
        #Now put the variables into arrays
        USRS[${COUNT}]=$USR
        CPUS[${COUNT}]=$CPU
        MEMS[${COUNT}]=$MEM
        CMDS[${COUNT}]=$CMD
        PIDS[${COUNT}]=$PID
        let COUNT=COUNT+1
done

echo -e "                \033[32m[  OK  ]\033[0m"

}

checkPs

# To access the array values do like the following
echo ${PIDS[50]} ${USRS[50]} ${CMDS[50]} ${CPUS[50]} ${MEMS[50]}
All this being said, if a process is taking up a lot of CPU usage, it doesn't necessarily need to be killed. Only if the server is being effected. If a process is running and no other processes need the CPU, it will take all the CPU it can get until it is done. You should only kill a high CPU using process if the system is actually being affected.

HTH

Forrest
I tried to execute that script
Quote:
./test: line 13: called: command not found
awk: cmd. line:2: ("USR=%s;CPU=%s;MEM=%s;CMD=%s;PID=%s", $1, $2, $3, $4, $5)}
awk: cmd. line:2: ^ syntax error
./test: line 13: called: command not found
awk: cmd. line:2: ("USR=%s;CPU=%s;MEM=%s;CMD=%s;PID=%s", $1, $2, $3, $4, $5)}
awk: cmd. line:2:
I tried to troubleshoot it, I didnt get the error
 
Old 12-13-2008, 09:33 PM   #7
jhyland87
LQ Newbie
 
Registered: Dec 2008
Posts: 25

Original Poster
Rep: Reputation: 15
Nevermind, your script works!

I guess I need to learn bash scripting! Any specific forums or tutorial sites you can think of that would be helpful in me learning?
 
Old 12-14-2008, 11:58 AM   #8
forrestt
Senior Member
 
Registered: Mar 2004
Location: Cary, NC, USA
Distribution: Fedora, Kubuntu, RedHat, CentOS, SuSe
Posts: 1,288

Rep: Reputation: 99
There are 2 pretty good guides at http://tldp.org/guides.html.

Specifically Bash Guide for Beginners and
Advanced Bash-Scripting Guide

HTH (And welcome to systems programming)

Forrest
 
  


Reply

Tags
bash, cpu, mem, php, programming, scripting



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Reading a bash variable in bash scripting problem freeindy Programming 3 11-27-2008 02:29 AM
Bash scripting help arturhawkwing Linux - General 1 08-10-2006 11:54 AM
Bash scripting SWAT Linux - Newbie 2 11-11-2003 03:21 AM
HELP with BASH scripting atwah Linux - Newbie 6 09-09-2003 01:10 AM
bash scripting -=MaGo=- Programming 16 08-30-2003 07:07 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:18 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration