Tuesday, July 31, 2007

UNIX Shell is Old Fashion ?

Is UNIX shell an old fashion stuff ?

UNIX has been with us for more 3.5 decades ( Unix History) and shell is the glue for UNIX commands to work together as well as interact with the system. Most of the commands are designed to do one thing and do it extremely well. Also, it is designed to work with other commands via the standard input, standard output and error. Output from one command can be the input to the next commands, the same concept can be extended to allow a chain of commands to achieve a specific goal.

Example, you may want to find out how many users with name starting "ch" that are using Korn shell (/bin/ksh)

$ egrep '^ch' /etc/passwd | cut -f7 -d: | grep -c /bin/ksh
4
Using regular expression "egrep" to find those starting with 'ch' in the password file, the output will be served as input to the "cut" command which output the 7th field based on colon (:) as the field separator. The output will be fed into "grep" command to count (-c) the number of lines

Here we can show you step by step to achieve our goal

$ cat /etc/passwd
root:x:0:0:Super-User:/:/sbin/sh
daemon:x:1:1::/:
bin:x:2:2::/usr/bin:
sys:x:3:3::/:
adm:x:4:4:Admin:/var/adm:
lp:x:71:8:Line Printer Admin:/usr/spool/lp:
uucp:x:5:5:uucp Admin:/usr/lib/uucp:
nuucp:x:9:9:uucp Admin:/var/spool/uucppublic:/usr/lib/uucp/uucico
smmsp:x:25:25:SendMail Message Submission Program:/:
listen:x:37:4:Network Admin:/usr/net/nls:
gdm:x:50:50:GDM Reserved UID:/:
webservd:x:80:80:WebServer Reserved UID:/:
nobody:x:60001:60001:NFS Anonymous Access User:/:
noaccess:x:60002:60002:No Access User:/:
nobody4:x:65534:65534:SunOS 4.x NFS Anonymous Access User:/:
chchan:x:1001:1000::/users/chchan:/bin/sh
hung:x:1002:1000::/users/hung:/bin/bash
chihung:x:1003:1000::/users/chihung:/bin/ksh
chi:x:1004:1000::/users/chi:/bin/ksh
manu:x:1005:1000::/users/manu:/bin/bash
chikeung:x:1006:1000::/users/chikeung:/bin/ksh
choo:x:1007:1000::/users/choo:/bin/ksh

$ egrep 'ch' /etc/passwd
chchan:x:1001:1000::/users/chchan:/bin/sh
chihung:x:1003:1000::/users/chihung:/bin/ksh
chi:x:1004:1000::/users/chi:/bin/ksh
chikeung:x:1006:1000::/users/chikeung:/bin/ksh
choo:x:1007:1000::/users/choo:/bin/ksh

$ egrep 'ch' /etc/passwd | cut -f7 -d:
/bin/sh
/bin/ksh
/bin/ksh
/bin/ksh
/bin/ksh

$ egrep 'ch' /etc/passwd | cut -f7 -d: | grep -c /bin/ksh
4

In fact, if you are an advanced user, you can do all that by using just "egrep" along.

$ egrep -c '^ch.*:/bin/ksh$' /etc/passwd
4
Powerful, isn't it. With regular expression, you can tell "egrep" that any line that starts with "ch" (anchor ^ - beginning of a line) followed by zero or more of any character. At the end of the line (anchor $ - end of a line), you need to match ":/bin/ksh". With "-c" option in "egrep", it will return the number of occurrence.

So, the answer to the question is - Unix is old, but not old-fashion, IMO. We should use whatever is approach to the task instead of reinventing the wheel.

Labels: ,

Saturday, July 28, 2007

Sun Grid Engine (SGE) Solving Recursion

During one of the demonstrations or benchmarks, whatever you want to call it, we were asked to use Sun Grid Engine (SGE) to show how it can be used to solve a recursive calculation.

The formula is like this: In = In-1 + In-2 , if n=0, I0 = 1 , if n=1, I1 = 1

If n=4, anwser is 8; if n=5, answer is 13

Easy, right? Yes, if you are going to program using your favourite programming language. But not using a grid engine, truss me.

Programming in a shell script way, it will be like this, easy peezy!

#! /bin/sh

calculate()
{
      echo `expr $1 + $2`
}


if [ $# -ne 1 ]; then
      echo "Usage: $0 <no>"
      exit 1
fi
num=$1


if [ $num -eq 0 ]; then
      result=1
elif [ $num -eq 1 ]; then
      result=2
else
      d1=`expr $num - 1`
      d2=`expr $num - 2`
      result1=`$0 $d1`
      result2=`$0 $d2`
      result=`calculate $result1 $result2`
fi
echo $result

Let's visualise the tree in order to get a feel of what we are going to deal with. Let's start with n=4

        4
       / \
      3    2
     / \  / \
    2  1  1  0
   / \
  1   0

How can we use SGE to simulate this recursion ? How can the 2 children know who their parent is after the jobs are submitted to execution nodes ? How to keep track of their results ? How can these results get pass back to the parent ? How to eventually stop and wind back up to the root node ?

Yes, these are the questions in my mind when I started off with this exercise. Becasue SGE is not a sub-second scheduler and therefore I can "qsub" 2 jobs and immediate establish the parent-child relationship using the "-hold_jid" (hold job dependency). In order for the children to know what their parent is, I parsed the "-v PARENT=value" in the "qsub", so that they can get the PARENT environment variable.

How to keep track of result at every stage ? I made use of some temporary files, however I need to ensure uniqueness of these files. We can accomplish this by taking a MD5 of the first 32 bytes (can be any size of bytes) in /dev/urandom device in Solaris.

At first, my SGE environment is configured with 12 slots and I can only run n=3 and n=4. When n=5, it simply ran out of slots. Here, I realised that slots/queue is very similar to memory/stack in a computer. In a recursive program, it has to push things onto the stack and let the pop/push of stack to sort itself out. If your stack size is too small, your recursive program will break which is similar to our slots in SGE, except that all those jobs will be on hold. They are going to hold forever until you "gdel" them.

As for n > 5, I have to increase the number of slots to make it work. Below shows the two scripts, namely the one doing all the recursion (rec.sh) and the one doing the calculation (cal.sh). It also shows "qstat" in action every 5 seconds interval. Job name "-N" in "qsub" is needed in order for the final value to be stored in the file "five".

$ cat rec.sh
#! /bin/sh
#$ -cwd
#$ -S /bin/sh
#$ -o /dev/null
#$ -e /dev/null


jndir=tmp
[ ! -d $jndir ] && mkdir $jndir


# loop around qacct to wait for result
getResult()
{
      while :
      do
              qacct -j $1 > /dev/null 2>&1
              if [ $? -eq 0 ]; then
                      cat $jndir/$1
                      return
              fi
              sleep 1
      done

      # it shouldn't reach here
      exit 1
}



if [ $# -ne 1 ]; then
      echo "Usage: $0 "
      exit 1
fi

. /opt/n1ge/default/common/settings.sh


number=$1
jobname=$JOB_NAME


if [ $number -eq 0 ]; then
      result=1
elif [ $number -eq 1 ]; then
      result=2
else
      d1=`expr $number - 1`
      d2=`expr $number - 2`
      jn1="jn-`dd if=/dev/urandom bs=32 count=1 2>/dev/null | digest -a md5`"
      jn2="jn-`dd if=/dev/urandom bs=32 count=1 2>/dev/null | digest -a md5`"

      qsub -N $jn1 -v PARENT=$jobname $0 $d1 > /dev/null 2>&1
      qsub -N $jn2 -v PARENT=$jobname $0 $d2 > /dev/null 2>&1

      # if there is parent-child relationship, establish it
      if [ "X$PARENT" != "X" ]; then
              qalter -hold_jid $jn1,$jn2 $jobname > /dev/null 2>&1
      fi

      result1=`getResult $jn1`
      result2=`getResult $jn2`

      result=`./cal.sh $result1 $result2`
fi


# write result to file
echo $result > $jndir/$jobname

$ cat cal.sh
#! /bin/sh

echo `expr $1 + $2`

$ qsub -N five rec.sh 5
Your job 463 ("five") has been submitted.

$ while :
do
qstat
sleep 5
done
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  464 0.00000 jn-1c84996 chihung      qw    07/27/2007 23:15:31                                    1
  465 0.00000 jn-0ed40af chihung      qw    07/27/2007 23:15:31                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  464 0.00000 jn-1c84996 chihung      qw    07/27/2007 23:15:31                                    1
  465 0.00000 jn-0ed40af chihung      qw    07/27/2007 23:15:31                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  464 0.00000 jn-1c84996 chihung      qw    07/27/2007 23:15:31                                    1
  465 0.00000 jn-0ed40af chihung      qw    07/27/2007 23:15:31                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  465 0.55500 jn-0ed40af chihung      hr    07/27/2007 23:15:46 all.q@sgeexec0                     1
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  466 0.00000 jn-66ad4b8 chihung      qw    07/27/2007 23:15:46                                    1
  467 0.00000 jn-1ddba59 chihung      qw    07/27/2007 23:15:46                                    1
  468 0.00000 jn-156ac6d chihung      qw    07/27/2007 23:15:46                                    1
  469 0.00000 jn-260acb5 chihung      qw    07/27/2007 23:15:46                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  465 0.55500 jn-0ed40af chihung      hr    07/27/2007 23:15:46 all.q@sgeexec0                     1
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  466 0.00000 jn-66ad4b8 chihung      qw    07/27/2007 23:15:46                                    1
  467 0.00000 jn-1ddba59 chihung      qw    07/27/2007 23:15:46                                    1
  468 0.00000 jn-156ac6d chihung      qw    07/27/2007 23:15:46                                    1
  469 0.00000 jn-260acb5 chihung      qw    07/27/2007 23:15:46                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  465 0.55500 jn-0ed40af chihung      hr    07/27/2007 23:15:46 all.q@sgeexec0                     1
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  466 0.00000 jn-66ad4b8 chihung      qw    07/27/2007 23:15:46                                    1
  467 0.00000 jn-1ddba59 chihung      qw    07/27/2007 23:15:46                                    1
  468 0.00000 jn-156ac6d chihung      qw    07/27/2007 23:15:46                                    1
  469 0.00000 jn-260acb5 chihung      qw    07/27/2007 23:15:46                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  465 0.55500 jn-0ed40af chihung      hr    07/27/2007 23:15:46 all.q@sgeexec0                     1
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  467 0.55500 jn-1ddba59 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  466 0.55500 jn-66ad4b8 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec2                     1
  469 0.55500 jn-260acb5 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec2                     1
  470 0.00000 jn-85a72cc chihung      qw    07/27/2007 23:16:01                                    1
  471 0.00000 jn-0ecd1c5 chihung      qw    07/27/2007 23:16:01                                    1
  472 0.00000 jn-f7b0c72 chihung      qw    07/27/2007 23:16:01                                    1
  473 0.00000 jn-c69525b chihung      qw    07/27/2007 23:16:01                                    1
  474 0.00000 jn-f7175e4 chihung      qw    07/27/2007 23:16:02                                    1
  475 0.00000 jn-f31a24c chihung      qw    07/27/2007 23:16:02                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  465 0.55500 jn-0ed40af chihung      hr    07/27/2007 23:15:46 all.q@sgeexec0                     1
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  467 0.55500 jn-1ddba59 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  466 0.55500 jn-66ad4b8 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec2                     1
  469 0.55500 jn-260acb5 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec2                     1
  470 0.00000 jn-85a72cc chihung      qw    07/27/2007 23:16:01                                    1
  471 0.00000 jn-0ecd1c5 chihung      qw    07/27/2007 23:16:01                                    1
  472 0.00000 jn-f7b0c72 chihung      qw    07/27/2007 23:16:01                                    1
  473 0.00000 jn-c69525b chihung      qw    07/27/2007 23:16:01                                    1
  474 0.00000 jn-f7175e4 chihung      qw    07/27/2007 23:16:02                                    1
  475 0.00000 jn-f31a24c chihung      qw    07/27/2007 23:16:02                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  465 0.55500 jn-0ed40af chihung      hr    07/27/2007 23:15:46 all.q@sgeexec0                     1
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  467 0.55500 jn-1ddba59 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  466 0.55500 jn-66ad4b8 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec2                     1
  469 0.55500 jn-260acb5 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec2                     1
  470 0.00000 jn-85a72cc chihung      qw    07/27/2007 23:16:01                                    1
  471 0.00000 jn-0ecd1c5 chihung      qw    07/27/2007 23:16:01                                    1
  472 0.00000 jn-f7b0c72 chihung      qw    07/27/2007 23:16:01                                    1
  473 0.00000 jn-c69525b chihung      qw    07/27/2007 23:16:01                                    1
  474 0.00000 jn-f7175e4 chihung      qw    07/27/2007 23:16:02                                    1
  475 0.00000 jn-f31a24c chihung      qw    07/27/2007 23:16:02                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  465 0.55500 jn-0ed40af chihung      hr    07/27/2007 23:15:46 all.q@sgeexec0                     1
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  467 0.55500 jn-1ddba59 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec1                     1
  471 0.55500 jn-0ecd1c5 chihung      hr    07/27/2007 23:16:16 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  466 0.55500 jn-66ad4b8 chihung      r     07/27/2007 23:16:01 all.q@sgeexec2                     1
  476 0.00000 jn-9ae8029 chihung      qw    07/27/2007 23:16:16                                    1
  477 0.00000 jn-d126937 chihung      qw    07/27/2007 23:16:16                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  465 0.55500 jn-0ed40af chihung      r     07/27/2007 23:15:46 all.q@sgeexec0                     1
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  467 0.55500 jn-1ddba59 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec1                     1
  471 0.55500 jn-0ecd1c5 chihung      hr    07/27/2007 23:16:16 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  476 0.00000 jn-9ae8029 chihung      qw    07/27/2007 23:16:16                                    1
  477 0.00000 jn-d126937 chihung      qw    07/27/2007 23:16:16                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  465 0.55500 jn-0ed40af chihung      r     07/27/2007 23:15:46 all.q@sgeexec0                     1
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  467 0.55500 jn-1ddba59 chihung      hr    07/27/2007 23:16:01 all.q@sgeexec1                     1
  471 0.55500 jn-0ecd1c5 chihung      hr    07/27/2007 23:16:16 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
  476 0.00000 jn-9ae8029 chihung      qw    07/27/2007 23:16:16                                    1
  477 0.00000 jn-d126937 chihung      qw    07/27/2007 23:16:16                                    1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  467 0.55500 jn-1ddba59 chihung      r     07/27/2007 23:16:01 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  467 0.55500 jn-1ddba59 chihung      r     07/27/2007 23:16:01 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  464 0.55500 jn-1c84996 chihung      hr    07/27/2007 23:15:46 all.q@sgeexec1                     1
  467 0.55500 jn-1ddba59 chihung      r     07/27/2007 23:16:01 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  464 0.55500 jn-1c84996 chihung      r     07/27/2007 23:15:46 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  464 0.55500 jn-1c84996 chihung      r     07/27/2007 23:15:46 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  464 0.55500 jn-1c84996 chihung      r     07/27/2007 23:15:46 all.q@sgeexec1                     1
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
  463 0.55500 five       chihung      r     07/27/2007 23:15:31 all.q@sgeexec2                     1
^C

$ ls tmp
five                                 jn-85a72cc20898241095d1489ebbb02ca7
jn-0ecd1c5c6721976cb9ca96c902fb1044  jn-9ae80293acaf8fc426bf7972ad8f6c38
jn-0ed40afa95dde7d92d3f5784fc397a2c  jn-c69525b4ba477a7ce110aab8a2438c45
jn-156ac6d58000f8c8c18b973959622464  jn-d126937687b91b5f6b14e1b642aedc60
jn-1c849969b8c86e907bd32255058313e6  jn-f31a24c2219734f3bef13f6ce5addf78
jn-1ddba5925ff899f36812527220fe19a9  jn-f7175e4d15c7e08a98a7c13915d0121e
jn-260acb532729915691a6b096eeb69e9b  jn-f7b0c72538b479c4615ad5abd0214660
jn-66ad4b80af12a4b4c7469e76d50406a7

$ cat tmp/five
13

Interesting ? For me, definitely.

Labels: ,

Thursday, July 19, 2007

OpenSolaris in a 4GB Thumb Drive, then Ubuntu

I brought a 4GB thumb drive a month ago to try loading OpenSolaris Belenix 0.6 LiveCD. In the web site, it says:
Usbdump integrated into the LiveCD. You can now boot from the CD pop in a USB stick and execute usbdump in a terminal to get BeleniX on USB.
Although it works, the /usr partition is mounted as read only and therefore I cannot do any package installation.

Anyway, the 4GB thumb moves on to Ubuntu 6.10. Why not the latest 7.04 'cos most of the people complained about having problem with this version. This article from Pendrivelinux.com has a very detailed step-by-step guide.

I partitioned 2GB FAT16 for the OS, and 2GB ext2 for my /opt. It is possible to do "apt-get install" to install packages.

What's next for my 4GB? I have no idea.

Labels: , , ,

SGE Grid Job Dependency

It is possible to describe SGE (Sun Grid Engine) job (or any other grid engine) dependency in a DAG (Directed Acyclic Graph) format. By taking advantage of the opensource Graphviz, it is very easy to document this dependency in DOT language format. Below shows you a sample DOT file:

$ cat job-dep.dot
digraph jobs101 {
        job_1 -> job_11;
        job_1 -> job_12;
        job_1 -> job_13;
        job_11 -> job_111;
        job_12 -> job_111;
        job_2 -> job_13;
        job_2 -> job_21;
        job_3 -> job_21;
        job_3 -> job_31;
}

With this DOT file, one can generate the graphical representation:

$ dot -Tpng -o job-dep.png job-dep.dot

It is also possible to derive the corresponding SGE commands by the following Tcl script.

$ cat ./dot2sge.tcl
#! /usr/local/bin/tclsh


if { $argc != 1 } {
        puts stderr "Usage: $argv0 "
        exit 1
}
set dotfile [lindex $argv 0]
if { [file exists $dotfile] == 0 } {
        puts stderr "Error. $dotfile does not exist"
        exit 2
}


# assume simple directed graph a -> b

set fp [open $dotfile r]
set data [read $fp]
close $fp


set sge_jobs {}
foreach i [split [lindex $data 2] {;}] {
        if { [regexp {(\w+)\s*->\s*(\w+)} $i x parent child] != 0 } {
                lappend sge_jobs $parent
                lappend sge_jobs $child

                lappend sge_job_rel($parent) $child
        }
}


# submit unique jobs, and hold
set queue all.q
set sge_unique_jobs [lsort -unique $sge_jobs]
foreach i $sge_unique_jobs {
        puts "qsub -h -q $queue -N $i job-submit.sh"
}


# alter the job dependency, but unhold after all the hold relationships are
# established
foreach i $sge_unique_jobs {
        if { [info exists sge_job_rel($i)] } {
                # with dependency
                puts "qalter -hold_jid [join $sge_job_rel($i) {,}] $i"
        }
}
foreach i $sge_unique_jobs {
        puts "qalter -h U $i"
}

Run this Tcl script to generate the SGE submission commands and alternation commands to register the job dependency

$ ./dot2sge.tcl job-dep.dot
qsub -h -q all.q -N job_1 job-submit.sh
qsub -h -q all.q -N job_11 job-submit.sh
qsub -h -q all.q -N job_111 job-submit.sh
qsub -h -q all.q -N job_12 job-submit.sh
qsub -h -q all.q -N job_13 job-submit.sh
qsub -h -q all.q -N job_2 job-submit.sh
qsub -h -q all.q -N job_21 job-submit.sh
qsub -h -q all.q -N job_3 job-submit.sh
qsub -h -q all.q -N job_31 job-submit.sh
qalter -hold_jid job_11,job_12,job_13 job_1
qalter -hold_jid job_111 job_11
qalter -hold_jid job_111 job_12
qalter -hold_jid job_13,job_21 job_2
qalter -hold_jid job_21,job_31 job_3
qalter -h U job_1
qalter -h U job_11
qalter -h U job_111
qalter -h U job_12
qalter -h U job_13
qalter -h U job_2
qalter -h U job_21
qalter -h U job_3
qalter -h U job_31

Below show the above proof-of-concept in action. So sit back....

#
# ----------below is a very simple script
#
$ cat job-submit.sh
#! /bin/sh
#$ -S /bin/sh

date
sleep 10


#
# ----------run all the qsub to submit jobs, but put them on hold
#
$ qsub -h -q all.q -N job_1 job-submit.sh
Your job 333 ("job_1") has been submitted.
$ qsub -h -q all.q -N job_11 job-submit.sh
Your job 334 ("job_11") has been submitted.
$ qsub -h -q all.q -N job_111 job-submit.sh
Your job 335 ("job_111") has been submitted.
$ qsub -h -q all.q -N job_12 job-submit.sh
Your job 336 ("job_12") has been submitted.
$ qsub -h -q all.q -N job_13 job-submit.sh
Your job 337 ("job_13") has been submitted.
$ qsub -h -q all.q -N job_2 job-submit.sh
Your job 338 ("job_2") has been submitted.
$ qsub -h -q all.q -N job_21 job-submit.sh
Your job 339 ("job_21") has been submitted.
$ qsub -h -q all.q -N job_3 job-submit.sh
Your job 340 ("job_3") has been submitted.
$ qsub -h -q all.q -N job_31 job-submit.sh
Your job 341 ("job_31") has been submitted.


#
# ----------show the status, all jobs are in hold position (hqw)
#
$ qstat -f
queuename                      qtype used/tot. load_avg arch          states
----------------------------------------------------------------------------
all.q@sgeexec0                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec1                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec2                 BIP   0/4       0.01     sol-amd64

############################################################################
 - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS
############################################################################
    333 0.00000 job_1      chihung      hqw   07/19/2007 21:04:34     1
    334 0.00000 job_11     chihung      hqw   07/19/2007 21:04:34     1
    335 0.00000 job_111    chihung      hqw   07/19/2007 21:04:34     1
    336 0.00000 job_12     chihung      hqw   07/19/2007 21:04:34     1
    337 0.00000 job_13     chihung      hqw   07/19/2007 21:04:34     1
    338 0.00000 job_2      chihung      hqw   07/19/2007 21:04:34     1
    339 0.00000 job_21     chihung      hqw   07/19/2007 21:04:34     1
    340 0.00000 job_3      chihung      hqw   07/19/2007 21:04:34     1
    341 0.00000 job_31     chihung      hqw   07/19/2007 21:04:34     1


#
# ----------register the job dependency
#
$ qalter -hold_jid job_11,job_12,job_13 job_1
modified job id hold list of job 333
   blocking jobs: 334,336,337
   exited jobs:   NONE
$ qalter -hold_jid job_111 job_11
modified job id hold list of job 334
   blocking jobs: 335
   exited jobs:   NONE
$ qalter -hold_jid job_111 job_12
modified job id hold list of job 336
   blocking jobs: 335
   exited jobs:   NONE
$ qalter -hold_jid job_13,job_21 job_2
modified job id hold list of job 338
   blocking jobs: 337,339
   exited jobs:   NONE
$ qalter -hold_jid job_21,job_31 job_3
modified job id hold list of job 340
   blocking jobs: 339,341
   exited jobs:   NONE


#
# ----------release all the holds and let SGE to sort itself out
#
$ qalter -h U job_1
modified hold of job 333
$ qalter -h U job_11
modified hold of job 334
$ qalter -h U job_111
modified hold of job 335
$ qalter -h U job_12
modified hold of job 336
$ qalter -h U job_13
modified hold of job 337
$ qalter -h U job_2
modified hold of job 338
$ qalter -h U job_21
modified hold of job 339
$ qalter -h U job_3
modified hold of job 340
$ qalter -h U job_31
modified hold of job 341


#
# ----------query SGE stats
#
$ qstat -f
queuename                      qtype used/tot. load_avg arch          states
----------------------------------------------------------------------------
all.q@sgeexec0                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec1                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec2                 BIP   0/4       0.01     sol-amd64

############################################################################
 - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS
############################################################################
    333 0.00000 job_1      chihung      hqw   07/19/2007 21:04:34     1
    334 0.00000 job_11     chihung      hqw   07/19/2007 21:04:34     1
    335 0.00000 job_111    chihung      qw    07/19/2007 21:04:34     1
    336 0.00000 job_12     chihung      hqw   07/19/2007 21:04:34     1
    337 0.00000 job_13     chihung      qw    07/19/2007 21:04:34     1
    338 0.00000 job_2      chihung      hqw   07/19/2007 21:04:34     1
    339 0.00000 job_21     chihung      qw    07/19/2007 21:04:34     1
    340 0.00000 job_3      chihung      hqw   07/19/2007 21:04:34     1
    341 0.00000 job_31     chihung      qw    07/19/2007 21:04:34     1


#
# ----------some jobs started to run
#
$ qstat -f
queuename                      qtype used/tot. load_avg arch          states
----------------------------------------------------------------------------
all.q@sgeexec0                 BIP   2/4       0.01     sol-amd64
    339 0.55500 job_21     chihung      r     07/19/2007 21:05:36     1
    341 0.55500 job_31     chihung      r     07/19/2007 21:05:36     1
----------------------------------------------------------------------------
all.q@sgeexec1                 BIP   1/4       0.01     sol-amd64
    335 0.55500 job_111    chihung      r     07/19/2007 21:05:36     1
----------------------------------------------------------------------------
all.q@sgeexec2                 BIP   1/4       0.01     sol-amd64
    337 0.55500 job_13     chihung      r     07/19/2007 21:05:36     1

############################################################################
 - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS
############################################################################
    333 0.00000 job_1      chihung      hqw   07/19/2007 21:04:34     1
    334 0.00000 job_11     chihung      hqw   07/19/2007 21:04:34     1
    336 0.00000 job_12     chihung      hqw   07/19/2007 21:04:34     1
    338 0.00000 job_2      chihung      hqw   07/19/2007 21:04:34     1
    340 0.00000 job_3      chihung      hqw   07/19/2007 21:04:34     1


$ qstat -f
queuename                      qtype used/tot. load_avg arch          states
----------------------------------------------------------------------------
all.q@sgeexec0                 BIP   2/4       0.01     sol-amd64
    339 0.55500 job_21     chihung      r     07/19/2007 21:05:36     1
    341 0.55500 job_31     chihung      r     07/19/2007 21:05:36     1
----------------------------------------------------------------------------
all.q@sgeexec1                 BIP   1/4       0.01     sol-amd64
    335 0.55500 job_111    chihung      r     07/19/2007 21:05:36     1
----------------------------------------------------------------------------
all.q@sgeexec2                 BIP   1/4       0.01     sol-amd64
    337 0.55500 job_13     chihung      r     07/19/2007 21:05:36     1

############################################################################
 - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS
############################################################################
    333 0.00000 job_1      chihung      hqw   07/19/2007 21:04:34     1
    334 0.00000 job_11     chihung      hqw   07/19/2007 21:04:34     1
    336 0.00000 job_12     chihung      hqw   07/19/2007 21:04:34     1
    338 0.00000 job_2      chihung      hqw   07/19/2007 21:04:34     1
    340 0.00000 job_3      chihung      hqw   07/19/2007 21:04:34     1


$ qstat -f
queuename                      qtype used/tot. load_avg arch          states
----------------------------------------------------------------------------
all.q@sgeexec0                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec1                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec2                 BIP   0/4       0.01     sol-amd64

############################################################################
 - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS
############################################################################
    333 0.00000 job_1      chihung      hqw   07/19/2007 21:04:34     1
    334 0.00000 job_11     chihung      qw    07/19/2007 21:04:34     1
    336 0.00000 job_12     chihung      qw    07/19/2007 21:04:34     1
    338 0.00000 job_2      chihung      qw    07/19/2007 21:04:34     1
    340 0.00000 job_3      chihung      qw    07/19/2007 21:04:34     1


$ qstat -f
queuename                      qtype used/tot. load_avg arch          states
----------------------------------------------------------------------------
all.q@sgeexec0                 BIP   2/4       0.01     sol-amd64
    338 0.55500 job_2      chihung      r     07/19/2007 21:05:51     1
    340 0.55500 job_3      chihung      r     07/19/2007 21:05:51     1
----------------------------------------------------------------------------
all.q@sgeexec1                 BIP   1/4       0.01     sol-amd64
    334 0.55500 job_11     chihung      r     07/19/2007 21:05:51     1
----------------------------------------------------------------------------
all.q@sgeexec2                 BIP   1/4       0.01     sol-amd64
    336 0.55500 job_12     chihung      r     07/19/2007 21:05:51     1

############################################################################
 - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS
############################################################################
    333 0.00000 job_1      chihung      hqw   07/19/2007 21:04:34     1


$ qstat -f
queuename                      qtype used/tot. load_avg arch          states
----------------------------------------------------------------------------
all.q@sgeexec0                 BIP   2/4       0.01     sol-amd64
    338 0.55500 job_2      chihung      r     07/19/2007 21:05:51     1
    340 0.55500 job_3      chihung      r     07/19/2007 21:05:51     1
----------------------------------------------------------------------------
all.q@sgeexec1                 BIP   1/4       0.01     sol-amd64
    334 0.55500 job_11     chihung      r     07/19/2007 21:05:51     1
----------------------------------------------------------------------------
all.q@sgeexec2                 BIP   1/4       0.01     sol-amd64
    336 0.55500 job_12     chihung      r     07/19/2007 21:05:51     1

############################################################################
 - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS
############################################################################
    333 0.00000 job_1      chihung      hqw   07/19/2007 21:04:34     1


$ qstat -f
queuename                      qtype used/tot. load_avg arch          states
----------------------------------------------------------------------------
all.q@sgeexec0                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec1                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec2                 BIP   0/4       0.01     sol-amd64

############################################################################
 - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS - PENDING JOBS
############################################################################
    333 0.00000 job_1      chihung      qw    07/19/2007 21:04:34     1


$ qstat -f
queuename                      qtype used/tot. load_avg arch          states
----------------------------------------------------------------------------
all.q@sgeexec0                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec1                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec2                 BIP   1/4       0.01     sol-amd64
    333 0.55500 job_1      chihung      r     07/19/2007 21:06:06     1


$ qstat -f
queuename                      qtype used/tot. load_avg arch          states
----------------------------------------------------------------------------
all.q@sgeexec0                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec1                 BIP   0/4       0.01     sol-amd64
----------------------------------------------------------------------------
all.q@sgeexec2                 BIP   1/4       0.01     sol-amd64
    333 0.55500 job_1      chihung      r     07/19/2007 21:06:06     1


#
# ----------output of all jobs, you can see job job_1/2/3 finished last
#
$ grep 2007 job_*.o*
job_111.o335:Thu Jul 19 21:05:36 SGT 2007
job_11.o334:Thu Jul 19 21:05:51 SGT 2007
job_12.o336:Thu Jul 19 21:05:51 SGT 2007
job_13.o337:Thu Jul 19 21:05:36 SGT 2007
job_1.o333:Thu Jul 19 21:06:06 SGT 2007
job_21.o339:Thu Jul 19 21:05:36 SGT 2007
job_2.o338:Thu Jul 19 21:05:51 SGT 2007
job_31.o341:Thu Jul 19 21:05:37 SGT 2007
job_3.o340:Thu Jul 19 21:05:52 SGT 2007

Another successful proof-of-concept. :-)

Labels: , ,

Wednesday, July 18, 2007

Awk-ing A Lot of Email Addresses

What statistics can you carry out if you have thousands of email addresses? You may want to find out the top 5 domains, and do you know that you can do it all in UNIX with these one-liners.

All these one-lines are tested on Solaris 10. One thing I want to point out that awk field separator (FS) does not honour what it documented in the man page: "FS: input field separator regular expression (default blank and tab)". However, nawk works perfectly well.

$ echo "chihungchan@somewhere.com.sg" | awk -F"[@.]" '{print NF}'
1
$ echo "chihungchan@somewhere.com.sg" | awk 'BEGIN{FS="[@.]"}{print NF}'
1
$ echo "chihungchan@somewhere.com.sg" | nawk -F"[@.]" '{print NF}'
4
$ echo "chihungchan@somewhere.com.sg" | nawk 'BEGIN{FS="[@.]"}{print NF}'
4

Back to the subject of finding the top 5 domain names:

$ nawk -F"@" '{++s[$2]}END{for(i in s){print i,s[i]}}' lots_of_emails.txt | sort -n -k 2 | tail -5
singnet.com.sg 83
yahoo.com.sg 137
yahoo.com 148
gmail.com 197
hotmail.com 221

$ nawk -F"[@.]" '{domain=sprintf("%s.%s",$(NF-1),$NF-1);++s[domain]}END{for(i in s){print i,s[i]}}' lots_of_emails.txt | sort -n -k 2 | tail -5
net.sg 50
yahoo.com 148
gmail.com 197
hotmail.com 221
com.sg 265

$ nawk -F"[@.]" '{++s[$NF]}END{for(i in s){print i,s[i]}}' lots_of_emails.txt | sort -n -k 2 | tail -5
id 6
net 7
my 8
sg 345
com 702

AWK is really powerful. You may want to read sed & awk from O'Relly to start with.

Labels: ,

Friday, July 13, 2007

Web Browser, Web Server

I booted up my notebook with Fedora and launched the Apache web server serving a simple html page for the home page. After that, I ran Ethereal to "capture" all the packets going through the wire.

My other notebook is directly linked with this web server via a cross cable so that I can visit this web server with Firefox and Internet Explorer. Below are the screen dumps of Ethereal. You can drill down to the TCP/IP stack to understand how client server communicate.

Firefox browsing:

Internet Explorer browsing:

Labels: , ,

Thursday, July 12, 2007

Network Statistics

"Netstat -s -P tcp" provides you with detail summary of the Tcp statistics. See below
$ netstat -s -P tcp

TCP     tcpRtoAlgorithm     =     4     tcpRtoMin           =   400
        tcpRtoMax           = 60000     tcpMaxConn          =    -1
        tcpActiveOpens      =   105     tcpPassiveOpens     =  6929
        tcpAttemptFails     =     9     tcpEstabResets      =    24
        tcpCurrEstab        =    10     tcpOutSegs          =14831657
        tcpOutDataSegs      =14504882   tcpOutDataBytes     =1579349845
        tcpRetransSegs      =   398     tcpRetransBytes     =116003
        tcpOutAck           =326541     tcpOutAckDelayed    =204020
        tcpOutUrg           =     0     tcpOutWinUpdate     =     0
        tcpOutWinProbe      =     0     tcpOutControl       = 14170
        tcpOutRsts          =    14     tcpOutFastRetrans   =    14
        tcpInSegs           =14736303
        tcpInAckSegs        =14290274   tcpInAckBytes       =1579351049
        tcpInDupAck         = 10033     tcpInAckUnsent      =     0
        tcpInInorderSegs    =14467627   tcpInInorderBytes   =681280146
        tcpInUnorderSegs    =    60     tcpInUnorderBytes   =  3120
        tcpInDupSegs        =    62     tcpInDupBytes       =  2184
        tcpInPartDupSegs    =     0     tcpInPartDupBytes   =     0
        tcpInPastWinSegs    =     0     tcpInPastWinBytes   =     0
        tcpInWinProbe       =     0     tcpInWinUpdate      =     0
        tcpInClosed         =     0     tcpRttNoUpdate      =   103
        tcpRttUpdate        =14283487   tcpTimRetrans       =   300
        tcpTimRetransDrop   =    12     tcpTimKeepalive     =  9353
        tcpTimKeepaliveProbe=  2967     tcpTimKeepaliveDrop =     0
        tcpListenDrop       =     0     tcpListenDropQ0     =     0
        tcpHalfOpenDrop     =     0     tcpOutSackRetrans   =    49

It is possible to timestamp each of these network metrics. If you collect them over a period of time, you can plot it with Gnuplot and study the trend of these TCP parameters.

This script should be able to do this job as a normal user and it will append timestamp and metrics to individual parameter files. So all you have to do is to loop through the script with a while loop. I will leave this to the reader as an exercise.

$ls
net.sh

$ cat net.sh
#! /bin/sh

timestamp=`date '+%Y%m%d%H%M%S'`


netstat -s -P tcp | \
sed -e 's/=/ /g' -e 's/TCP//' | \
nawk -v ts=$timestamp '
NF==2 {
        cmd=sprintf("echo %s %s >> %s",ts,$2,$1)
        system(cmd)
}
NF==4 {
        cmd=sprintf("echo %s %s >> %s",ts,$2,$1)
        system(cmd)
        cmd=sprintf("echo %s %s >> %s",ts,$4,$3)
        system(cmd)
}'

$ ls
net.sh                tcpInDupBytes         tcpInWinUpdate tcpOutSackRetrans     tcpRttNoUpdate
tcpActiveOpens        tcpInDupSegs          tcpListenDrop tcpOutSegs            tcpRttUpdate
tcpAttemptFails       tcpInInorderBytes     tcpListenDropQ0 tcpOutUrg             tcpTimKeepalive
tcpCurrEstab          tcpInInorderSegs      tcpMaxConn tcpOutWinProbe        tcpTimKeepaliveDrop
tcpEstabResets        tcpInPartDupBytes     tcpOutAck tcpOutWinUpdate       tcpTimKeepaliveProbe
tcpHalfOpenDrop       tcpInPartDupSegs      tcpOutAckDelayed tcpPassiveOpens       tcpTimRetrans
tcpInAckBytes         tcpInPastWinBytes     tcpOutControl tcpRetransBytes       tcpTimRetransDrop
tcpInAckSegs          tcpInPastWinSegs      tcpOutDataBytes tcpRetransSegs
tcpInAckUnsent        tcpInUnorderBytes     tcpOutDataSegs tcpRtoAlgorithm
tcpInClosed           tcpInUnorderSegs      tcpOutFastRetrans     tcpRtoMax
tcpInDupAck           tcpInWinProbe         tcpOutRsts            tcpRtoMin

$ more tcpActiveOpens
20070712081804 29

Labels: ,

Wednesday, July 11, 2007

Netstat and Process Mapping

If you want to find out the mapping between the network connections to processes, you may need to install lsof on your SPARC server. However, you may not want to do that in a production server especially the server is your customer.

So the question is how can we uncover these information using the standard Solaris utilities. One more challenge is that it has to run on Solaris 8 (my friend's server).

Let's take a look at the output of netstat

# netstat -n -P tcp

TCP: IPv4
   Local Address        Remote Address    Swind Send-Q Rwind Recv-Q  State
-------------------- -------------------- ----- ------ ----- ------ -------
10.0.12.242.32787    10.0.12.242.32776    49152      0 49152      0 ESTABLISHED
10.0.12.242.32776    10.0.12.242.32787    49152      0 49152      0 ESTABLISHED
10.0.12.242.32790    10.0.12.242.1521     49152      0 49152      0 ESTABLISHED
10.0.12.242.1521     10.0.12.242.32790    49152      0 49152      0 ESTABLISHED
10.0.12.242.1521     10.0.12.241.1159     65207      0 48269      0 ESTABLISHED
10.0.12.242.1521     10.0.12.241.1289     64543      0 49353      0 ESTABLISHED
10.0.12.242.22       1.2.3.4.47292 65223      0 50400     52 ESTABLISHED

Active UNIX domain sockets
Address  Type          Vnode     Conn  Local Addr      Remote Addr
300055edac0 stream-ord 300055f3300 00000000 /var/tmp/.oracle/s#134.1
300055edc88 stream-ord 300055f3118 00000000 /var/tmp/.oracle/sEXTPROC

What the expect output will be like this:

# ./my-lsof
10.0.12.242:32790 <-> 10.0.12.242:1521 = ora_pmon_chihung (324)
10.0.12.242:1521 <-> 10.0.12.242:32790 = /app/oracle/product/9.2.0/bin/tnslsnr (134)
10.0.12.242:1521 <-> 10.0.12.241:1159 = oraclechihung (12351)
10.0.12.242:1521 <-> 10.0.12.241:1289 = oraclechihung (12353)
10.0.12.242:22 <-> 1.2.3.4:47292 = /usr/lib/ssh/sshd (13412)

The below script is tested on Solaris 9 (I do not have a Solaris 8)

#! /bin/sh

proc=`(cd /proc; ls -1 | awk '$1>3{print}') | sort -n`

netstat -n -P tcp | \
awk '/----/{start=1;continue} start==1&&/^$/ {exit} start==1{print $1, $2}' | \
while :
do
        read line
        if [ "$line" = "" ]; then
                break
        fi
        laddr=`echo $line | nawk '{split($1,a,"."); printf("%s.%s.%s.%s",a[1],a[2],a[3],a[4])}'`
        lport=`echo $line | nawk '{split($1,a,"."); printf("%s",a[5])}'`
        raddr=`echo $line | nawk '{split($2,a,"."); printf("%s.%s.%s.%s",a[1],a[2],a[3],a[4])}'`
        rport=`echo $line | nawk '{split($2,a,"."); printf("%s",a[5])}'`

        # solaris 8 does not have pargs
        for p in $proc
        do
                pfiles $p 2>/dev/null | egrep "peername.*$raddr.* $rport\$" > /dev/null 2>&1
                if [ $? -eq 0 ]; then
                        comm=`ps -e -o 'pid,comm' | awk '$1=='$p'{printf("%s (%d)\n",$2,$1)}'`
                        echo "$laddr:$lport <-> $raddr:$rport = $comm"
                        break
                fi
        done
done

Buy me coffee if this is useful...
BTW, this only process those connections in ESTABLISHED state.

Labels: ,