Re: Process Information (756 Views)
Reply
Valued Contributor
G V R Shankar
Posts: 197
Registered: ‎02-08-2004
Message 1 of 20 (756 Views)
Accepted Solution

Process Information

Hi All,

Is there a way to know the process start time after 24 hours?

After 24 hours, it starts showing the date instead of time.

Thank you.

Ravi
Honored Contributor
Steven Schweda
Posts: 9,096
Registered: ‎02-23-2005
Message 2 of 20 (756 Views)

Re: Process Information

> After 24 hours, it starts showing the date
> instead of time.

What is this "it"?

As usual, showing actual commands with their
actual output can be more helpful than vague
descriptions and interpretations.

"uname -a" would be a good place to start,
too.
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 3 of 20 (756 Views)

Re: Process Information

I assume you are talking about ps(1)?
I don't see any evidence of how to get more details. Except by rolling your own with pstat_getproc(2)?
Honored Contributor
Laurent Menase
Posts: 1,079
Registered: ‎11-06-2003
Message 4 of 20 (756 Views)

Re: Process Information

UNIX95= ps -o pid,comm,etime

etime gives the time in day-h:m:s
else pstat_getproc() in a c program
Valued Contributor
G V R Shankar
Posts: 197
Registered: ‎02-08-2004
Message 5 of 20 (756 Views)

Re: Process Information

Could you please share a script that can give me the process start time using the elapsed time?

Thank you very much.

Ravi.
Honored Contributor
Laurent Menase
Posts: 1,079
Registered: ‎11-06-2003
Message 6 of 20 (756 Views)

Re: Process Information

I use C
#include
#include
char *sep="::-x"; int coefs[]={1,60,3600,3600*24,0};
main(c,v)
int c;
char **v;
{
int t;
char buf[255];
int dt=0;
int icoef=0;
time(&t);
while (*sep)
{
char *r;
char *p=strrchr(v[1],*sep++);
r=v[1];
if (p!=NULL )
{
*p=0;
r=p+1;
}
dt=dt+atoi(r) *(coefs[icoef++]);
*r=0;
}
t-=dt;
strftime(buf,256,"%y/%m/%d %H:%M:%S",localtime(&t));
printf("%s\n",buf);
}

cc etimetodate.c -o etimetodate
etimetodate 2-02:01:01
Valued Contributor
G V R Shankar
Posts: 197
Registered: ‎02-08-2004
Message 7 of 20 (756 Views)

Re: Process Information

Hi,

I have created a user with c shell and run the script as mentioned.

I am receiving the following error.

Warning 942: "etimetodate.c", line 12 # Types 'long *' and 'int *' are not assignment-compatible.
time(&t);
^
Warning 942: "etimetodate.c", line 27 # Types 'const long *' and 'int *' are not assignment-compatible.
strftime(buf,256,"%y/%m/%d %H:%M:%S",localtime(&t));

Could you please help me? I am not good a C.

Ravi.
Honored Contributor
Laurent Menase
Posts: 1,079
Registered: ‎11-06-2003
Message 8 of 20 (756 Views)

Re: Process Information

it is not important,
since we compile in 32bits mode, long and int are compatible.

if you want to avoid them just replace
int t;
by
long t;

Happy new year
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 9 of 20 (756 Views)

Re: Process Information

>I have created a user with C shell and run the script as mentioned.

Why would you want to use the scummy C shell? Also this is a C program, not a script.

>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.

>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);

>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));

>#include

Note: The correct ANSI C header is .
Valued Contributor
G V R Shankar
Posts: 197
Registered: ‎02-08-2004
Message 10 of 20 (756 Views)

Re: Process Information

Hi Laurent,

I have modified int t to long t. It works.

The new program looks like following, please correct me if I am wrong.

#include
#include
char *sep="::-x"; int coefs[]={1,60,3600,3600*24,0};
main(c,v)
int c;
char **v;
{
long t;
char buf[255];
int dt=0;
int icoef=0;
time(&t);
while (*sep)
{
char *r;
char *p=strrchr(v[1],*sep++);
r=v[1];
if (p!=NULL )
{
*p=0;
r=p+1;
}
dt=dt+atoi(r) *(coefs[icoef++]);
*r=0;
}
t-=dt;
strftime(buf, 256, "%y/%m/%d %H:%M:%S", localtime(&t));
printf("%s\n",buf);
}

Thank you very much.

Hi Dennis,

I have modifed the script to the following. This also works. Any other suggestions.

#include
#include
char *sep="::-x"; int coefs[]={1,60,3600,3600*24,0};
main(c,v)
int c;
char **v;
{
time_t t;
char buf[255];
int dt=0;
int icoef=0;
t = time(NULL);
while (*sep)
{
char *r;
char *p=strrchr(v[1],*sep++);
r=v[1];
if (p!=NULL )
{
*p=0;
r=p+1;
}
dt=dt+atoi(r) *(coefs[icoef++]);
*r=0;
}
t-=dt;
strftime(buf, sizeof(buf), "%y/%m/%d %H:%M:%S", localtime(&t));
printf("%s\n",buf);
}

Valued Contributor
G V R Shankar
Posts: 197
Registered: ‎02-08-2004
Message 11 of 20 (756 Views)

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.
Acclaimed Contributor
James R. Ferguson
Posts: 21,184
Registered: ‎07-06-2000
Message 12 of 20 (756 Views)

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...
Valued Contributor
G V R Shankar
Posts: 197
Registered: ‎02-08-2004
Message 13 of 20 (756 Views)

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.
Valued Contributor
G V R Shankar
Posts: 197
Registered: ‎02-08-2004
Message 14 of 20 (756 Views)

Re: Process Information

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

Cheers,

Ravi.
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 15 of 20 (756 Views)

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;)
Acclaimed Contributor
James R. Ferguson
Posts: 21,184
Registered: ‎07-06-2000
Message 16 of 20 (756 Views)

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...
Honored Contributor
Laurent Menase
Posts: 1,079
Registered: ‎11-06-2003
Message 17 of 20 (756 Views)

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);
}

Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 18 of 20 (756 Views)

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;
}
Honored Contributor
Laurent Menase
Posts: 1,079
Registered: ‎11-06-2003
Message 19 of 20 (756 Views)

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.
Acclaimed Contributor
Dennis Handly
Posts: 25,277
Registered: ‎03-06-2006
Message 20 of 20 (756 Views)

Re: Process Information

>Laurent: no need for ps anymore

Yes, I noticed that, though the tool may want to take more than one PID.
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.