How to get date+time of when a process started

Hi,

Is there a way to find out when a process was started/spawned?

$: ps -ef | grep 1234 | grep -v grep
  oracle  1234  1888   3   Feb 28 ?        8142:12 oracleblah (LOCAL=NO)
$: uname -a
SunOS [hostname] 5.11 11.4.77.182.2 sun4v sparc sun4v non-global-zone

On Linux, ps -eo pid,lstart,cmd works fine but this command does not work on Solaris.

Any idea on how to do the same for Solaris to get the same STARTED output below from the Linux ps output.

$ uname -a
Linux [hostname] 5.15.0-200.131.27.el8uek.x86_64 #2 SMP Wed Oct 4 22:19:10 PDT 2023 x86_64 x86_64 x86_64 GNU/Linux
$ ps -eo pid,lstart,cmd | head
    PID                  STARTED CMD
      1 Mon Jan 13 16:06:15 2025 /usr/lib/systemd/systemd --switched-root --system --deserialize 17
      2 Mon Jan 13 16:06:15 2025 [kthreadd]
      3 Mon Jan 13 16:06:15 2025 [rcu_gp]
      4 Mon Jan 13 16:06:15 2025 [rcu_par_gp]
      5 Mon Jan 13 16:06:15 2025 [slub_flushwq]
      6 Mon Jan 13 16:06:15 2025 [netns]
      8 Mon Jan 13 16:06:15 2025 [kworker/0:0H-events_highpri]
     10 Mon Jan 13 16:06:15 2025 [mm_percpu_wq]
     11 Mon Jan 13 16:06:15 2025 [rcu_tasks_rude_]
[ oracle@apse2cod821 / | () ] $

Maybe some trick where I run as below:

$: show-ps-timestamp 1234
1234 STARTED Fri Feb 28 02:46:21 NZDT 2025

Here is a script from the net for Solaris which might be helpful:

show-ps-timestamp

#!/bin/bash

pid=$1
etime=$(ps -o etime= -p "$pid" | awk '{print $1}')

# Convert elapsed time to start time
start_time=$(TZ=GMT date -d "$(TZ=GMT date) - $etime ago" '+%a %b %d %T %Z %Y')

echo "$pid STARTED $start_time"

Example

$ ./show-ps-timestamp 1234
1234 STARTED Fri Feb 28 02:46:21 NZDT 2025

Solaris date does not have -d.
Of course you can install GNU date, but then you can as well install GNU ps that has -o lstart

You can try -o stime

ps -eo pid,stime,cmd

but the output format is not nice.

For a certain process, substitute -e by -p pid

ps -p 1234 -o pid,stime,cmd

Suppress the header with

ps -p 1234 -o pid= -o stime= -o cmd=

To get the start time of a process on Solaris, you can use the ps command with the -o option to display the elapsed time since the process started, and then calculate the start time based on the current time. parapcc. com

#!/bin/bash

pid=$1

# Get the elapsed time in the format [[dd-]hh:]mm:ss
etime=$(ps -o etime= -p "$pid")

# Extract days, hours, minutes, and seconds from the elapsed time
days=0
hours=0
minutes=0
seconds=0

if [[ $etime == *-* ]]; then
    days=$(echo $etime | awk -F'-' '{print $1}')
    etime=$(echo $etime | awk -F'-' '{print $2}')
fi

hours=$(echo $etime | awk -F':' '{print $1}')
minutes=$(echo $etime | awk -F':' '{print $2}')
seconds=$(echo $etime | awk -F':' '{print $3}')

# Convert elapsed time to seconds
elapsed_seconds=$((days*86400 + hours*3600 + minutes*60 + seconds))

# Get the current time in seconds since the epoch
current_time=$(perl -e 'print time')

# Calculate the start time in seconds since the epoch
start_time=$((current_time - elapsed_seconds))

# Convert the start time to a human-readable format
start_time_formatted=$(perl -e 'print scalar localtime('$start_time')')

echo "$pid STARTED $start_time_formatted"

This works if zero hours are shown as 00 or 0, e.g. 00:00:01
Not in Linux, where zero hours are not shown, e.g. 00:01

Here comes a fix.
The etime can be desribed by a regex.

#!/bin/bash

pid=$1

# Get the elapsed time in the format [[dd-]hh:]mm:ss
etime=$(ps -o etime= -p "$pid")

# Extract days, hours, minutes, and seconds from the elapsed time
[[ $etime =~ (([0-9]+)-)?(([0-9]+):)?([0-9]+):([0-9]+)$ ]]
typeset -i days=10#0${BASH_REMATCH[2]} hours=10#0${BASH_REMATCH[4]} minutes=10#0${BASH_REMATCH[5]} seconds=10#0${BASH_REMATCH[6]}

# Convert elapsed time to seconds
elapsed_seconds=$((days*86400 + hours*3600 + minutes*60 + seconds))

# Get the current time in seconds since the epoch
current_time=$(date +%s)

# Calculate the start time in seconds since the epoch
start_time=$((current_time - elapsed_seconds))

# Convert the start time to a human-readable format
start_time_formatted=$(perl -e 'print scalar localtime(shift)' "$start_time")

echo "$pid STARTED $start_time_formatted"

Thanks @MadeInGermany, you have won the solution for this round :slight_smile:

I tried all and I believe the errors are as what you 've mentioned.
The date/time matches exactly what is the logon time on the database too.

$: ./show-ps-timestamp-00.bash 4164
-> MadeInGermany
4164 STARTED Fri Feb 28 02:46:21 2025
$: ./show-ps-timestamp-01.bash 4164
-> parapcc0
./show-ps-timestamp-01.bash: line 25: 08: value too great for base (error token is "08")
4164 STARTED Fri Mar  7 11:26:14 2025
$: ./show-ps-timestamp-02.bash 4164
-> Neo
date: illegal option -- d
usage:  date [-u] mmddHHMM[[cc]yy][.SS]
        date [-u] [+format]
        date -a [-]sss[.fff]
4164 STARTED

SQL> select logon_time from v$session where paddr = ( select addr from v$process where spid = 4164 ) ;

LOGON_TIME
-------------------
2025-02-28 02:46:21

1 row selected.

This is a misfeature in bash. In a number context a number with a 0 prefix is considered octal.
Therefore the effort to prefix each value with a 10# so the number is always considered decimal (base 10), but then a missing value (the regex can give an empty value) gives error, so another 0 is prefixed.
You could do this later as well:

elapsed_seconds=$(( 10#0$days*86400 + 10#0$hours*3600 + 10#0$minutes*60 + 10#0$seconds ))