91 Renicing Tasks by Process Name


#91 Renicing Tasks by Process Name

There are many times when it's useful to change the priority of a specific task, whether it's an IRC or chat server that's supposed to use only "spare" cycles, an MP3 player app or file download that has become less important, or a real-time CPU monitor being increased in priority. The renice command, however, requires you to specify the process ID, which can be a hassle. A much more useful approach is to have a script that matches process name to process ID and then renices the specified application.

The Code

 #!/bin/sh # renicename - Renices the job that matches the specified name. user=""; tty=""; showpid=0; niceval="+1"        # initialize while getopts "n:u:t:p" opt; do   case $opt in    n ) niceval="$OPTARG";               ;;    u ) if [ ! -z "$tty" ] ; then          echo " 
 #!/bin/sh # renicename - Renices the job that matches the specified name. user=""; tty=""; showpid=0; niceval="+1" # initialize while getopts "n:u:t:p" opt; do case $opt in n ) niceval="$OPTARG"; ;; u ) if [ ! -z "$tty" ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi user=$OPTARG ;; t ) if [ ! -z "$ user " ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi tty=$OPTARG ;; p ) showpid=1; ;; ? ) echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 echo "Default niceval change is \"$niceval\" (plus is lower" >&2 echo "priority, minus is higher, but only root can go below 0)" >&2 exit 1 esac done shift $(($OPTIND - 1)) # eat all the parsed arguments if [ $# -eq 0 ] ; then echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 exit 1 fi if [ ! -z "$tty" ] ; then pid=$(ps cu -t $tty  awk "/ $1/ { print \\$2 }") elif [ ! -z "$user" ] ; then pid=$(ps cu -U $user  awk "/ $1/ { print \\$2 }") else pid=$(ps cu -U ${USER:-LOGNAME}  awk "/ $1/ { print \$2 }") fi if [ -z "$pid" ] ; then echo "$0: no processes match pattern $1" >&2 ; exit 1 elif [ ! -z "$(echo $pid  grep ' ')" ] ; then echo "$0: more than one process matches pattern ${1}:" if [ ! -z "$tty" ] ; then runme="ps cu -t $tty" elif [ ! -z "$user" ] ; then runme="ps cu -U $user" else runme="ps cu -U ${USER:-LOGNAME}" fi eval $runme  \ awk "/ $1/ { printf \" user %-8.8s pid %-6.6s job %s\n\", \ \$1,\$2,\$11 }" echo "Use -u user or -t tty to narrow down your selection criteria." elif [ $showpid -eq 1 ] ; then echo $pid else # ready to go: let's do it! echo -n "Renicing job \"" echo -n $(ps cp $pid  sed 's/ [ ]*/ /g'  tail -1  cut -d\ -f5-) echo "\" ($pid)" renice $niceval $pid fi exit 0 
: error: -u and -t are mutually exclusive." >&2 exit 1 fi user=$OPTARG ;; t ) if [ ! -z "$user" ] ; then echo "
 #!/bin/sh # renicename - Renices the job that matches the specified name. user=""; tty=""; showpid=0; niceval="+1" # initialize while getopts "n:u:t:p" opt; do case $opt in n ) niceval="$OPTARG"; ;; u ) if [ ! -z "$tty" ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi user=$OPTARG ;; t ) if [ ! -z "$ user " ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi tty=$OPTARG ;; p ) showpid=1; ;; ? ) echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 echo "Default niceval change is \"$niceval\" (plus is lower" >&2 echo "priority, minus is higher, but only root can go below 0)" >&2 exit 1 esac done shift $(($OPTIND - 1)) # eat all the parsed arguments if [ $# -eq 0 ] ; then echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 exit 1 fi if [ ! -z "$tty" ] ; then pid=$(ps cu -t $tty  awk "/ $1/ { print \\$2 }") elif [ ! -z "$user" ] ; then pid=$(ps cu -U $user  awk "/ $1/ { print \\$2 }") else pid=$(ps cu -U ${USER:-LOGNAME}  awk "/ $1/ { print \$2 }") fi if [ -z "$pid" ] ; then echo "$0: no processes match pattern $1" >&2 ; exit 1 elif [ ! -z "$(echo $pid  grep ' ')" ] ; then echo "$0: more than one process matches pattern ${1}:" if [ ! -z "$tty" ] ; then runme="ps cu -t $tty" elif [ ! -z "$user" ] ; then runme="ps cu -U $user" else runme="ps cu -U ${USER:-LOGNAME}" fi eval $runme  \ awk "/ $1/ { printf \" user %-8.8s pid %-6.6s job %s\n\", \ \$1,\$2,\$11 }" echo "Use -u user or -t tty to narrow down your selection criteria." elif [ $showpid -eq 1 ] ; then echo $pid else # ready to go: let's do it! echo -n "Renicing job \"" echo -n $(ps cp $pid  sed 's/ [ ]*/ /g'  tail -1  cut -d\ -f5-) echo "\" ($pid)" renice $niceval $pid fi exit 0 
: error: -u and -t are mutually exclusive." >&2 exit 1 fi tty=$OPTARG ;; p ) showpid=1; ;; ? ) echo "Usage:
 #!/bin/sh # renicename - Renices the job that matches the specified name. user=""; tty=""; showpid=0; niceval="+1" # initialize while getopts "n:u:t:p" opt; do case $opt in n ) niceval="$OPTARG"; ;; u ) if [ ! -z "$tty" ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi user=$OPTARG ;; t ) if [ ! -z "$ user " ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi tty=$OPTARG ;; p ) showpid=1; ;; ? ) echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 echo "Default niceval change is \"$niceval\" (plus is lower" >&2 echo "priority, minus is higher, but only root can go below 0)" >&2 exit 1 esac done shift $(($OPTIND - 1)) # eat all the parsed arguments if [ $# -eq 0 ] ; then echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 exit 1 fi if [ ! -z "$tty" ] ; then pid=$(ps cu -t $tty  awk "/ $1/ { print \\$2 }") elif [ ! -z "$user" ] ; then pid=$(ps cu -U $user  awk "/ $1/ { print \\$2 }") else pid=$(ps cu -U ${USER:-LOGNAME}  awk "/ $1/ { print \$2 }") fi if [ -z "$pid" ] ; then echo "$0: no processes match pattern $1" >&2 ; exit 1 elif [ ! -z "$(echo $pid  grep ' ')" ] ; then echo "$0: more than one process matches pattern ${1}:" if [ ! -z "$tty" ] ; then runme="ps cu -t $tty" elif [ ! -z "$user" ] ; then runme="ps cu -U $user" else runme="ps cu -U ${USER:-LOGNAME}" fi eval $runme  \ awk "/ $1/ { printf \" user %-8.8s pid %-6.6s job %s\n\", \ \$1,\$2,\$11 }" echo "Use -u user or -t tty to narrow down your selection criteria." elif [ $showpid -eq 1 ] ; then echo $pid else # ready to go: let's do it! echo -n "Renicing job \"" echo -n $(ps cp $pid  sed 's/ [ ]*/ /g'  tail -1  cut -d\ -f5-) echo "\" ($pid)" renice $niceval $pid fi exit 0 
[-n niceval] [-u user-t tty] [-p] pattern" >&2 echo "Default niceval change is \"$niceval\" (plus is lower" >&2 echo "priority, minus is higher, but only root can go below 0)" >&2 exit 1 esac done shift $(($OPTIND - 1)) # eat all the parsed arguments if [ $# -eq 0 ] ; then echo "Usage:
 #!/bin/sh # renicename - Renices the job that matches the specified name. user=""; tty=""; showpid=0; niceval="+1" # initialize while getopts "n:u:t:p" opt; do case $opt in n ) niceval="$OPTARG"; ;; u ) if [ ! -z "$tty" ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi user=$OPTARG ;; t ) if [ ! -z "$ user " ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi tty=$OPTARG ;; p ) showpid=1; ;; ? ) echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 echo "Default niceval change is \"$niceval\" (plus is lower" >&2 echo "priority, minus is higher, but only root can go below 0)" >&2 exit 1 esac done shift $(($OPTIND - 1)) # eat all the parsed arguments if [ $# -eq 0 ] ; then echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 exit 1 fi if [ ! -z "$tty" ] ; then pid=$(ps cu -t $tty  awk "/ $1/ { print \\$2 }") elif [ ! -z "$user" ] ; then pid=$(ps cu -U $user  awk "/ $1/ { print \\$2 }") else pid=$(ps cu -U ${USER:-LOGNAME}  awk "/ $1/ { print \$2 }") fi if [ -z "$pid" ] ; then echo "$0: no processes match pattern $1" >&2 ; exit 1 elif [ ! -z "$(echo $pid  grep ' ')" ] ; then echo "$0: more than one process matches pattern ${1}:" if [ ! -z "$tty" ] ; then runme="ps cu -t $tty" elif [ ! -z "$user" ] ; then runme="ps cu -U $user" else runme="ps cu -U ${USER:-LOGNAME}" fi eval $runme  \ awk "/ $1/ { printf \" user %-8.8s pid %-6.6s job %s\n\", \ \$1,\$2,\$11 }" echo "Use -u user or -t tty to narrow down your selection criteria." elif [ $showpid -eq 1 ] ; then echo $pid else # ready to go: let's do it! echo -n "Renicing job \"" echo -n $(ps cp $pid  sed 's/ [ ]*/ /g'  tail -1  cut -d\ -f5-) echo "\" ($pid)" renice $niceval $pid fi exit 0 
[-n niceval] [-u user-t tty] [-p] pattern" >&2 exit 1 fi if [ ! -z "$tty" ] ; then pid=$(ps cu -t $tty awk "/ / { print \ }") elif [ ! -z "$user" ] ; then pid=$(ps cu -U $user awk "/ / { print \ }") else pid=$(ps cu -U ${USER:-LOGNAME} awk "/ / { print $2 }") fi if [ -z "$pid" ] ; then echo "
 #!/bin/sh # renicename - Renices the job that matches the specified name. user=""; tty=""; showpid=0; niceval="+1" # initialize while getopts "n:u:t:p" opt; do case $opt in n ) niceval="$OPTARG"; ;; u ) if [ ! -z "$tty" ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi user=$OPTARG ;; t ) if [ ! -z "$ user " ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi tty=$OPTARG ;; p ) showpid=1; ;; ? ) echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 echo "Default niceval change is \"$niceval\" (plus is lower" >&2 echo "priority, minus is higher, but only root can go below 0)" >&2 exit 1 esac done shift $(($OPTIND - 1)) # eat all the parsed arguments if [ $# -eq 0 ] ; then echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 exit 1 fi if [ ! -z "$tty" ] ; then pid=$(ps cu -t $tty  awk "/ $1/ { print \\$2 }") elif [ ! -z "$user" ] ; then pid=$(ps cu -U $user  awk "/ $1/ { print \\$2 }") else pid=$(ps cu -U ${USER:-LOGNAME}  awk "/ $1/ { print \$2 }") fi if [ -z "$pid" ] ; then echo "$0: no processes match pattern $1" >&2 ; exit 1 elif [ ! -z "$(echo $pid  grep ' ')" ] ; then echo "$0: more than one process matches pattern ${1}:" if [ ! -z "$tty" ] ; then runme="ps cu -t $tty" elif [ ! -z "$user" ] ; then runme="ps cu -U $user" else runme="ps cu -U ${USER:-LOGNAME}" fi eval $runme  \ awk "/ $1/ { printf \" user %-8.8s pid %-6.6s job %s\n\", \ \$1,\$2,\$11 }" echo "Use -u user or -t tty to narrow down your selection criteria." elif [ $showpid -eq 1 ] ; then echo $pid else # ready to go: let's do it! echo -n "Renicing job \"" echo -n $(ps cp $pid  sed 's/ [ ]*/ /g'  tail -1  cut -d\ -f5-) echo "\" ($pid)" renice $niceval $pid fi exit 0 
: no processes match pattern " >&2 ; exit 1 elif [ ! -z "$(echo $pid grep ' ')" ] ; then echo "
 #!/bin/sh # renicename - Renices the job that matches the specified name. user=""; tty=""; showpid=0; niceval="+1" # initialize while getopts "n:u:t:p" opt; do case $opt in n ) niceval="$OPTARG"; ;; u ) if [ ! -z "$tty" ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi user=$OPTARG ;; t ) if [ ! -z "$ user " ] ; then echo "$0: error: -u and -t are mutually exclusive." >&2 exit 1 fi tty=$OPTARG ;; p ) showpid=1; ;; ? ) echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 echo "Default niceval change is \"$niceval\" (plus is lower" >&2 echo "priority, minus is higher, but only root can go below 0)" >&2 exit 1 esac done shift $(($OPTIND - 1)) # eat all the parsed arguments if [ $# -eq 0 ] ; then echo "Usage: $0 [-n niceval] [-u user-t tty] [-p] pattern" >&2 exit 1 fi if [ ! -z "$tty" ] ; then pid=$(ps cu -t $tty  awk "/ $1/ { print \\$2 }") elif [ ! -z "$user" ] ; then pid=$(ps cu -U $user  awk "/ $1/ { print \\$2 }") else pid=$(ps cu -U ${USER:-LOGNAME}  awk "/ $1/ { print \$2 }") fi if [ -z "$pid" ] ; then echo "$0: no processes match pattern $1" >&2 ; exit 1 elif [ ! -z "$(echo $pid  grep ' ')" ] ; then echo "$0: more than one process matches pattern ${1}:" if [ ! -z "$tty" ] ; then runme="ps cu -t $tty" elif [ ! -z "$user" ] ; then runme="ps cu -U $user" else runme="ps cu -U ${USER:-LOGNAME}" fi eval $runme  \ awk "/ $1/ { printf \" user %-8.8s pid %-6.6s job %s\n\", \ \$1,\$2,\$11 }" echo "Use -u user or -t tty to narrow down your selection criteria." elif [ $showpid -eq 1 ] ; then echo $pid else # ready to go: let's do it! echo -n "Renicing job \"" echo -n $(ps cp $pid  sed 's/ [ ]*/ /g'  tail -1  cut -d\ -f5-) echo "\" ($pid)" renice $niceval $pid fi exit 0 
: more than one process matches pattern :" if [ ! -z "$tty" ] ; then runme="ps cu -t $tty" elif [ ! -z "$user" ] ; then runme="ps cu -U $user" else runme="ps cu -U ${USER:-LOGNAME}" fi eval $runme \ awk "/ / { printf \" user %-8.8s pid %-6.6s job %s\n\", \ $1,$2,$11 }" echo "Use -u user or -t tty to narrow down your selection criteria." elif [ $showpid -eq 1 ] ; then echo $pid else # ready to go: let's do it! echo -n "Renicing job \"" echo -n $(ps cp $pid sed 's/ [ ]*/ /g' tail -1 cut -d\ -f5-) echo "\" ($pid)" renice $niceval $pid fi exit 0

How It Works

This script borrows liberally from the earlier Script #52, Killing Processes by Name, which does a similar mapping of process name to process ID, but then kills the jobs, rather than just lowering their priority.

In this situation, you don't want to accidentally renice a number of matching processes (imagine renicename - n 10 "*" , for example), so the script fails if more than one process matches the criteria. Otherwise, it makes the change specified and lets the actual renice program report any errors that may have been encountered .

Running the Script

You have a number of different possible options when running this script: -n val allows you to specify the desired nice (job priority) value. The default is specified as niceval=1 . The -u user flag allows matching processes to be limited by user, while -t tty allows a similar filter by terminal name. To see just the matching process ID and not actually renice the application, use the -p flag. In addition to one or more flags, renicename requires a command pattern that will be compared to the running process names on the system to ascertain which of the processes match.

The Results

First off, here are the results when there is more than one matching process:

 $  renicename "vim"  renicename: more than one process matches pattern vim:   user taylor   pid 10581    job vim   user taylor   pid 10949    job vim Use -u user or -t tty to narrow down your selection criteria. 

I subsequently quit one of these processes and ran the same command:

 $  renicename "vim"  Renicing job "vim" (10949) 11131: old priority 0, new priority 1 

We can confirm that this worked by using the -alr (or -al ) flags to ps :

 $  ps -alr  UID   PID  PPID CPU PRI NI    VSZ    RSS STAT  TT     TIME COMMAND     0   439   438   0  31  0  14048    568 Ss   std  0:00.84 login -pf taylor   501   440   439   0  31  0   1828    756 S    std  0:00.56 -bash (bash)     0 10577   438   0  31  0  14048    572 Ss    p2  0:00.83 login -pf taylor   501 10578 10577   0  31  0   1828    760 S     p2  0:00.16 -bash (bash)   501 10949 10578   0  30  1  11004   2348 SN+   p2  0:00.09 vim reniceme     0 11152   440   0  31  0   1372    320 R+   std  0:00.01 ps -alr 

Notice that the vim process (10949) has a nice value (the NI column) of 1, while everything else I'm running has a nice value of 0, the standard user priority level.

Hacking the Script

An interesting addendum to this script is another script that watches for certain programs to be launched and automatically renices them to a set priority; this can be helpful if certain Internet services or applications tend to consume most of the CPU resources, for example. The script uses renicename to map process name to process ID and then checks the process's current nice level and issues a renice if the nice level specified as a command argument is higher (a lesser priority) than the current level:

 #!/bin/sh # watch_and_nice - Watches for the specified process name, and renices it #  to the desired value when seen. renicename="$HOME/bin/renicename" if [ $# -ne 2 ] ; then   echo "Usage: $(basename 
 #!/bin/sh # watch_and_nice - Watches for the specified process name, and renices it # to the desired value when seen. renicename="$HOME/bin/renicename" if [ $# -ne 2 ] ; then echo "Usage: $(basename $0) desirednice jobname" >&2 exit 1 fi pid="$($renicename -p "$2")" if [ ! -z "$(echo $pid  sed 's/[0-9]*//g')" ] ; then echo "Failed to make a unique match in the process table for $2" >&2 exit 1 fi currentnice="$(ps -lp $pid  tail -1  awk '{print $6}')" if [ $1 -gt $currentnice ] ; then echo "Adjusting priority of $2 to $1" renice $1 $pid fi exit 0 
) desirednice jobname" >&2 exit 1 fi pid="$($renicename -p "")" if [ ! -z "$(echo $pid sed 's/[0-9]*//g')" ] ; then echo "Failed to make a unique match in the process table for " >&2 exit 1 fi currentnice="$(ps -lp $pid tail -1 awk '{print }')" if [ -gt $currentnice ] ; then echo "Adjusting priority of to " renice $pid fi exit 0

Within a cron job, this script could be used to ensure that certain apps are pushed to the desired priority within a few minutes of being launched.




Wicked Cool Shell Scripts. 101 Scripts for Linux, Mac OS X, and Unix Systems
Wicked Cool Shell Scripts
ISBN: 1593270127
EAN: 2147483647
Year: 2004
Pages: 150
Authors: Dave Taylor

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net