Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!evax!utacfd!letni!mic!convex!convex.COM From: tchrist@convex.COM (Tom Christiansen) Newsgroups: comp.unix.misc Subject: Re: Who's in my Directory ? Message-ID: <109418@convex.convex.com> Date: 28 Nov 90 20:14:10 GMT References: <1990Nov21.013355.16798@maverick.ksu.ksu.edu> <1990Nov21.185812.19152@athena.mit.edu> Sender: news@convex.com Reply-To: tchrist@convex.COM (Tom Christiansen) Organization: CONVEX Software Development, Richardson, TX Lines: 85 In article , barnett@crdgw1.ge.com scrawls: >Here is a shell script that might work for BSD systems. I call it 'pswd' >Output looks like: > > barnett 4777 co 0:00 PWD=/home/kreskin/u0/barnett > etc. > >This only works is a processes current working directory is visible >with a ps wweuax command. > >#!/bin/sh ># this script is like ps but prints out the current directory also >ps wweuax!| awk ' >/PWD/ { ># print user PID TTY COMMAND > printf "%8s %8s %2s %14s ",$1,$2,$7,$10 ; > for (i=11;i if (index($i,"PWD=") == 1) printf "%s",$i ; > printf "\n" ; > }' Sorry, but very few programs keep your cwd in the $PWD envariable. So this won't work very often. I would still go with fuser for SysV boxes, fstat for BSD ones, or ofiles if you can't find any better. Furthermore, you cannot process ps output with awk that way. That STAT column is fixed width but with an unknown number of elements. If you try to do it all with fixed width columns, you'll be unhappy again because sometimes things like SZ or RSS get really big (at least on my machine) and push things aside. If you parse 'ps l' output, then you have to deal with the WCHAN column being there or not, depending. I'm not just going to criticize. Here's a solution I came up with. After running 'ps l' through this filter, you can split on white space and guarantee that the 0th field is the flags, ..., the 9th one is the wait channel (which is 0 if originally missing), the 10th field is the process run state with spaces set to dots to yield things like ".D.<." or ".R..." or "VS.N.". Field #13..$#F are the commands. #!/usr/local/bin/perl # fixps: put 'ps l' output into reliable fields # warning: sub-optimal perl code follows while (<>) { # feed me output from 'ps l' if (/COMMAND/) { print; next; } ($fixed, $float) = /^(\s*\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+ )(.*)$/; ($wchan, $stat, $tt, $time, $command) = ($float =~ /^(.{8}) (.{5}) (..) +(\d+:\d+) +(.*)/); $wchan = ' 0 ' if $wchan eq ' '; $stat =~ s/ /./g; print "$fixed $wchan $stat $tt $time $command\n"; } So you then do something like this: ps axl | fixps | something_else Where something else can do this if you don't want to just split into one big array. This is now *much* easier to deal with. #!/usr/local/bin/perl while (<>) { ($flags, $uid, $pid, $ppid, $cp, $pri, $nice, $size, $rss, $wchan, $state, $tty, $time, $command) = split(' ',$_,14); if ($state =~ /V/) { # found a vector job } if ($uid != 0 && $state =~ />/) { # OR: if ($uid != 0 && $nice < 0) { # negatively reniced non-root process } if ($ppid == 1 && $uid != 0 && !(hex($flags) & 0x00800000) && $tty ne "?") { # SLOGIN bit # someone logged out with something in background } } --tom