LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Recalculate variable for each pass of an until loop (https://www.linuxquestions.org/questions/linux-newbie-8/recalculate-variable-for-each-pass-of-an-until-loop-788495/)

wideyes 02-11-2010 12:11 PM

Recalculate variable for each pass of an until loop
 
Hello. I am trying to write a script that will find any user on the server running more than one instance of the epiphany web browser process, then kill all their epiphany pids. (This is necessary sometimes to cure lockups, and repeat processes are the telltale sign in this case). I have tried implementing the until loop:

Code:

USER=`ps aux | grep epiphany | grep -v grep | sort | uniq -d -w 5 | awk '{print $1}'`

until [[ "$USER" == "" ]]

do
  ps aux | grep epiphany | grep -v grep | grep $USER | awk '{print $2}' | sudo xargs kill

done

Unfortunately, the script only calculates the USER variable once at the beginning of the script. Fair enough, that's how it's written. My question is, how would I get the USER variable to update for each pass of the until loop so that it could cure multiple users of this ailment if necessary? That is, calculate $USER, kill their epiphany pids, repeat those two steps until the $USER variable comes up blank, then exit.

Thanks for any thoughts.

rweaver 02-11-2010 12:45 PM

You need to create your variable in the loop somewhere, I would probably do it something like this (untested).

Code:

for i in $(ps aux | grep epiphany | grep -v grep | sort | uniq -d -w5 | awk '{print $1}'); do
  killall -u $i epiphany
done

(edit: note this doesn't recalculate the variable every run, but it will run multiple iterations for the users it finds -- eg: if there are three users with epiphany open multiple times it will loop three times.)

rnturn 02-11-2010 01:12 PM

Quote:

Originally Posted by wideyes (Post 3860525)
Your script:
Code:

USER=`ps aux | grep epiphany | grep -v grep | sort | uniq -d -w 5 | awk '{print $1}'`

until [[ "$USER" == "" ]]
do
  ps aux | grep epiphany | grep -v grep | grep $USER | awk '{print $2}' | sudo xargs kill

done


What about:
Code:

set `ps aux | grep epiphany | grep -v grep | sort | uniq -d -w 5 | awk '{print $1}'`

while [ $# -gt 0 ]
do
    USER=$1
    ps aux | grep epiphany | grep -v grep | grep $USER | awk '{print $2}' | sudo xargs kill
    shift
done

or even:
Code:

ps aux | grep epiphany | grep -v grep | sort | uniq -d -w 5 | awk '{print $1}' | while read USER
do
    echo "Whacking processes for user ${USER}..."
    ps aux | grep epiphany | grep -v grep | grep $USER | awk '{print $2}' | sudo xargs kill
done

I'm not entirely sure this is what will do the trick (not being sure how to duplicate your problem to test the above code)

wideyes 02-11-2010 02:12 PM

Aha! I had a suspicion shift could be used on the variable, but I didn't think to assign USER to argument $1 (which, in hindsight, is pretty obvious). Good idea.

I like the succinctness of rweaver's suggestion as well. I'm still learning what I can and can't accomplish with the for loop. I'm going to go and test these little lumps. I'll update with my thoughts!

wideyes 02-11-2010 07:07 PM

Ok! Here's the complete script I went with:
Code:

#! /bin/bash
echo "Scanning workstations for frozen internet browsers..."
TEST=`ps aux | grep epiphany | grep -v grep | sort | uniq -d -w5 | awk '{print $1}'`
if [[ $TEST == "" ]];
  then
        echo "No frozen browsers found. If problem persists, restart the workstation."
  else
        for USER in $TEST
          do
                killall -u $USER epiphany 2> /dev/null
                echo "$USER has been exorcised!"
        done
fi

Many thanks for all the suggestions.

I had initially

I noticed that the killall command outputs some errors that make it appear to be not working (maybe due to my script), but it is effective, so I redirected standard error to the bitbucket. If I like it well enough, I'll just set it up as a cron task to run every 15 min. or so (my workplace is full of folks who just love to pull up densely resource-hungry webpages on their thin clients. If only I could script human bahavior!).

catkin 02-12-2010 01:23 AM

The disadvantage of set and shift solutions is that they loose the original command arguments (unless done in a subshell). rweaver's for <var> in <list> solution does not have this disadvantage.


All times are GMT -5. The time now is 10:04 PM.