1753400 Members
7235 Online
108792 Solutions
New Discussion юеВ

Re: Process Information

 
SOLVED
Go to solution
G V R Shankar
Valued Contributor

Re: Process Information

Hi Laurent and all,

Forgot to mention. I wish you and your beloved ones a very happy and prosperous new year 2010.

Thank you.

Ravi.
James R. Ferguson
Acclaimed Contributor

Re: Process Information

Hi Ravi:

You could use Perl. In fact, instead of manually running 'ps' you could use this script:

# cat ./ps_etimes
#!/usr/bin/perl
#@(#) Show processes with elapsed time as a start timestamp - JRF
use strict;
use warnings;
use POSIX qw(strftime);
my @weights = ( 1, 60, 3600, 86400 );
my $now = time();
$ENV{UNIX95} = 1;
open my $fh, 'ps -eo pid,comm,etime|' or die "Can't fork: $!\n";
while (<$fh>) {
next if $. == 1;
chomp;
my ( $pid, $comm, $etime ) = split;
my @a = reverse split /[:-]/, $etime;
my $t = 0;
for ( 0 .. @a - 1 ) {
$t += $a[$_] * $weights[$_];
}
printf "%5d %-15s %s\n", $pid, $comm,
strftime( "%Y/%m/%d %H:%M:%S", localtime( $now - $t ) );
}
1;

The output is a process list as if you had done:

# UNIX95= ps -eo pid,comm,etime

...except the header line is suppressed and the 'etime' field is computed to the process instantiation timestamp instead of the elapsed 'd-h:m:s' format it normally takes.

Simply run as:

# ./ps_etimes

...or for a particular process (for example):

# ./ps_etimes | grep diaglogd

Regards (and Happy New Year)!

...JRF...
G V R Shankar
Valued Contributor

Re: Process Information

Hi James,

The perl script works like a charm.

Thank you very much.

Hi Laurent and Dennis,

Thank you very much for the C programs.

Cheers,

Ravi.
G V R Shankar
Valued Contributor

Re: Process Information

I got want I was looking for. Both the C and Perl programs meet my objectives.

Cheers,

Ravi.
Dennis Handly
Acclaimed Contributor

Re: Process Information

>JRF: # UNIX95= ps -eo pid,comm,etime
... except the header line is suppressed

If you want to suppress the header line, why don't you use this instead:
UNIX95=EXTENDED_PS ps -e -opid= -ocomm= -oetime=
(And remove: next if $. == 1;)
James R. Ferguson
Acclaimed Contributor

Re: Process Information

Hi:

> Dennis: If you want to suppress the header line, why don't you use this instead:
UNIX95=EXTENDED_PS ps -e -opid= -ocomm= -oetime=
(And remove: next if $. == 1;)

I certainly could have, but chose to skip the first line to keep the command easier to ammend. Of course in doing so, I sacrificed a few extra CPU cycles :-)

Regards!

...JRF...
Laurent Menase
Honored Contributor

Re: Process Information

>>Laurent: It is not important, since we >compile in 32bits mode, long and int are >compatible.
>
>It is better to be correct in all modes.
yes, I agree for a long program, but what I mean is that it doesn't change the result

>>if you want to avoid them just replace
>
>The correct typedef is time_t, not int nor >long. See time(2).

>>time(&t);

>A faster version that doesn't make the >kernel sweat is:
>t = time(NULL);

Indeed you avoid the copyout of a long
which for a repetitive program run could have side effect

>>char buf[255];
>>strftime(buf, 256, "%y/%m/%d %H:%M:%S", >localtime(&t));
>
>Instead of getting the sizes wrong, you >should use sizeof, provided buf isn't a
>parm:
>strftime(buf, sizeof(buf), "%y/%m/%d >%H:%M:%S", localtime(&t));
Yes; indeed it is much better and due to quick and dirty copy/past. ( at least a 256 would have been better even if in that case,it will have no side effect since the format output is much smaller than the 256 bytes)

>>#include
>Note: The correct ANSI C header is .
yes, it is old habits, like the old style main declaration,
main(c,v)
int c;
char **v;

the new way is main(int c,char *v[])
you could also tell that #include is missing so printf will not be prototyped.

I could also have included the call to pstat_getproc() in the program


#include
#include
#include
main(int c,char *v[])
{
struct pst_status pst;
long t;
int pid;
char buf[256];
pid=atoi(v[1]);
if(pstat_getproc( &pst,sizeof(pst), 0 , pid)<0)
{
perror("pstat");
exit(0);
}
t=pst.pst_start;
strftime(buf,sizeof(buf),"%y/%m/%d %H:%M:%S",localtime(&t));
printf("%s\n",buf);
}

Dennis Handly
Acclaimed Contributor

Re: Process Information

You can also use strptime(3) to parse your time:
#include
#include
#include
int main(int argc, char **argv) {
int i;
time_t t, t2;
int dt;
struct tm tm1;
char buf[255];
t = time(NULL);
for (i = 1; i < argc; ++i) {
// use %j to collect days
char *result = strptime(argv[i], "%j-%H:%M:%S", &tm1);
if (result) {
if (*result != '\0')
printf("strptime bad result: %s\n", result);
} else {
printf("strptime error\n");
}
dt = ((((tm1.tm_yday + 1) * 24 + tm1.tm_hour) * 60) + tm1.tm_min) * 60 +
tm1.tm_sec;
t2 = t - dt;
strftime(buf, sizeof(buf), "%Y/%m/%d %H:%M:%S", localtime(&t2));
printf("%s\n",buf);
}
return 0;
}
Laurent Menase
Honored Contributor

Re: Process Information

with the
#include
#include
#include
main(int c,char *v[])
{
struct pst_status pst;
long t;
int pid;
char buf[256];
pid=atoi(v[1]);
if(pstat_getproc( &pst,sizeof(pst), 0 , pid)<0)
{
perror("pstat");
exit(0);
}
t=pst.pst_start;
strftime(buf,sizeof(buf),"%y/%m/%d %H:%M:%S",localtime(&t));
printf("%s\n",buf);
}
no need for ps anymore
./a.out pid will give the start date for the given process.
Dennis Handly
Acclaimed Contributor

Re: Process Information

>Laurent: no need for ps anymore

Yes, I noticed that, though the tool may want to take more than one PID.