Find out who is monopolizing or eating the CPUs

When you need to determine which process is monopolizing or eating the CPUs. Following command will displays the top 10 CPU users on the Linux system.

ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10

or

ps -eo pcpu,pid,user,args | sort -r -k1 | less

Output
%CPU PID USER COMMAND
96 2148 vivek /usr/lib/vmware/bin/vmware-vmx -C /var/lib/vmware/Virtual Machines/Ubuntu 64-bit/Ubuntu 64-bit.vmx -@ ""
0.7 3358 mysql /usr/libexec/mysqld --defaults-file=/etc/my.cnf --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --skip-locking --socket=/var/lib/mysql/mysql.sock
0.4 29129 lighttpd /usr/bin/php
0.4 29128 lighttpd /usr/bin/php
0.4 29127 lighttpd /usr/bin/php
0.4 29126 lighttpd /usr/bin/php
0.2 2177 vivek [vmware-rtc]
0.0 9 root [kacpid]
0.0 8 root [khelper]

If you’re interested in more information on Linux CPU utilization then check out the related article on nixCraft here.

Wrong password doofus!

There is a fun feature available within the sudo program. You’ll get an insult when you do the wrong thing such as enter your password incorrectly.

To turn the feature on you’ll need to use the following command:

sudo visudo

(always use visudo when you need to edit your sudoers file as it has a self-check system that won’t let you screw it up.)

Change the “Defaults”, by adding “,insults to the back
For example:

Defaults !lecture,tty_tickets,!fqdn,insults

Save, and enjoy the action!
(Note: use “sudo -K” to clear your sudo session)

Referenced original

my own setlock source code

I’ve added the “force” options, as I needed it for the project I’m working on.

#!/bin/bash

usage()
{
  echo "usage: setlock [ -fFnN ] [ -xX ] [ -v ] [ -V ] file program [ arg ... ]"
  echo " Options"
  echo "    -f: No delay. If fn is locked by another process, try to force ownership by trying to kill the process that has the lock."
  echo "    -F: No delay. If fn is locked by another process, bruteforce ownership by killing the process that has the lock (-9)."
  echo "    -n: No delay. If fn is locked by another process, setlock gives up."
  echo "    -N: (Default.) Delay. If fn is locked by another process, setlock waits until it can obtain a new lock."
  echo "    -x: If fn cannot be created or locked, setlock exits zero."
  echo "    -X: (Default.) If fn cannot be created or locked, setlock prints an error message and exits nonzero."
  echo "    -v: Verbose messaging"
  echo "    -V: Show the version"
  exit 1
}
version()
{
  echo "Version 0.1"
  usage
}
verbose()
{
  if [ "$VERBOSE" = "y" ] ; then 
    echo "$1"
  fi
}
cleanup()
{
  if [ "$SETLOCK" = "y" ] ; then
    killlock
    clear_lock 
  fi 
}
trap "cleanup"
set_lock()
{
  verbose "set lock"
  echo $$ >> $LOCK
  SETLOCK=y
}
clear_lock()
{
  verbose "Clear lock"
  rm $LOCK >/dev/null 2>&1 
}
killlock()
{
  pids=`cat $LOCK 2>/dev/null` 
  for pid in $pids 
  do
    verbose "Kill $1 on process $pid" 
    kill $1 $pid >/dev/null 2>&1
  done
}
run_command()
{ 
  set_lock
  verbose "Running command"
  eval bash -c "$CMD" 
  RET=$?
  verbose "Command done - exit value = $RET"
  clear_lock
  RET=$? 
  exit $RET
}
no_wait()
{
  verbose "No waiting" 
  exit $EXITCODE
}
wait_nice()
{
  verbose "Waiting nice"
  while [ -f "$LOCK" ] ; do
    sleep 1 
  done
  run_command
}
force_kill()
{
  killlock
  run_command 
} 
force_brute()
{
  killlock -9 
  run_command
}

FORCE=n
DELAY=y
EXITCODE=1
VERBOSE=n
OPTS=0
while getopts "f F n N x X v V" o ; do
  case $o in
    f) FORCE=y DELAY=n;;
    F) FORCE=b DELAY=n;;
    n) DELAY=n;;
    N) DELAY=y;;
    x) EXITCODE=0;;
    X) EXITCODE=1;;
    v) VERBOSE=y;;
    V) version;; 
  esac
  let OPTS=$OPTS+1
done

if [ $# -lt 2 ] ; then
  verbose "Not enough parameters given"
  usage
fi

APTS=0
while [ $APTS -lt $OPTS ]  ; do
  shift 
  let APTS=$APTS+1
done

LOCK=$1
shift
CMD=$*

if [ -z "$LOCK" ] ; then
  verbose "No lockfile given"
  usage
fi

if [ -z "$CMD" ] ; then
  verbose "No command given"
  usage
fi

if [ -f "$LOCK" ] ; then
  if [ "$DELAY" = "y" ] ; then
    wait_nice
  else
    case "$FORCE" in
      "n") no_wait;;
      "y") force_kill;;
      "b") force_brute;;
      *) exit 99;;
    esac
  fi 
else
  run_command
fi

Feel free to use it, yet I’m publishing it here under the GPL license

bash : locking issues – example with setlock

Something that kept me busy for a while. An internal (bash) framework sometimes (Isn’t that great! -sigh-) gave unexpected results. Sometimes the timings were too long, and sometimes data was missing. In the end, it was due to a locking issue. A program tried to execute something while forcing an internal lock. Yet the program was waiting until the lock was released. But when in some cases when two programs do this, this causes a deadlock.

The code below is a way to get around this deadlock. It’s an example using “setlock”, yet it shows the concept. Instead of waiting for the program to release the lock (default behaviour with “setlock”), you can script a small loop that comes back after a few seconds. Yet you have to setup the locking mechanism in a manner that it won’t wait for the lock (option -n for “setlock”).

SUME="bash -c "
SETLOCK="path-to-setlock"
EXECUTE="your-script"
PARAMETERS="your-parameters"
ID="your-unique-id-for-locking"
# usage of a control structure with non-wait locking
# this is done to avoid locking issues ^^
var0=0
LIMIT=3
SNOOZE=5
while [ "$var0" -lt "$LIMIT" ]
do
  var0=`expr $var0 + 1`
  eval $SUME "$SETLOCK -n $TMPDIR/lock_$ID $EXECUTE $PARAMETERS 2>/dev/null "  2>/dev/null
  EC=$?
  if [ $EC -eq 0 ] ; then
     var0=`expr $LIMIT + 1`
  else 
     sleep $SNOOZE
  fi
done
exit $EC

bash getopts

If you’re scripting with bash, and haven’t encountered the getopts function, then you should read the following
article @ linux.com.

The getopts function is an -easy to use- function when you’re working with script where parameters and flags have to be set.

Example

while getopts ":f:p:c:s:d r v" o ; do
        case $o in
                f ) FILE=$OPTARG;;
                p ) PARA=$OPTARG;;
                c ) VALU=$OPTARG;;
                s ) DELI=$OPTARG;;
                d ) DEBUG=y;;
                r ) RO=y;;
                v ) echo $VERSION
                    exit 0;;
        esac
done

The options with a colon (“:”) in front of them need to have an argument set. Yet if there is a space, then no argument is needed.

So -r -d & -v are the flags. Where the others are options/parameters that can be set.

Bash subshell & piping to a loop

When setting/changing variables within the scope of a subshell. And then attempt to use those variables outside the scope of this subshell won’t give the ‘expected result’.
A subshell has to be seen as a totally seperate process with it’s own environment.
(check a previous entry about processes)

Now the above might seem logical: Subshell, seperate process, … okay. Let’s say you want to pipe the output of a certain command thru a loop. In this loop you can manipulate/filter/… the data. In some cases you might want to set a flag if a certain criteria is met. Here is where it all comes into play. When you pipe an output to any kind of loop, it’ll become a subshell.

So as you might have guessed. The flag you wanted to set won’t cross it’s subshell borders. So you won’t be able to see it outside the loop. And yet again, an output that you might not have expected.

More info about “bash gotchas” can be found here