Format ps STIME on Linux - linux

I recently moved to Linux from HP-UX and I noticed that STIME of a process is in "MonthDate" format(e.g. Apr21) while on HP-UX it was "Month Date"(e.g. Apr 21). There is no space between month and date. Is there a way to get a space between month and date?
HP-UX:
root 16773 1 1 Jul 15 ? 67:23 /opt/ssh/sbin/sshd
Linux:
oper 24494 23075 0 Apr21 ? 00:00:00 sshd: oper#pts/8

So once again I am digging procps-ng sources for the same function pr_stime() sources. You may be interested in the command above that function.
No, you can't parse stime consistently. The format is not specified in the standard. The output from procps-ng/ps varies depending how long ago the process was created. Procps-ng/ps uses 3 format strings depending on how long time ago the process has started. If your script depends on it, you may be surprised they all will stop working on new years eve when ps starts using %Y format string for stime column.
For determining how long time ago a process was started on linux, use etimes or etime with procps-ng/ps.

Related

GNU date command not allowing for far away years?

When running the following command with GNU date :
date -d "20145-01-23"
I get the following result :
date: invalid date `20145-01-23'
However, the manual states that year can be any number :
For numeric months, the ISO 8601 format ‘year-month-day’ is allowed, where year is any positive number [...]
Thus, two questions :
is this a bug ? or am I misunderstanding something ?
how to obtain the same behavior than BSD date, which accepts this as a valid date ?
This works for me, using GNU coreutils 8.24:
$ date -d "20145-01-23"
Sat Jan 23 00:00:00 PST 20145
I'm not certain of this explanation (UPDATE: looks like my guess was correct), but my guess is that you're on a system with a 32-bit time_t rather than 64 bits. With 32 bits, the only representable dates are from Fri 1901-12-13 20:45:52 UTC (231 seconds before the epoch) to Tue 2038-01-19 03:14:07 UTC (231-1 seconds after the epoch).
If this is the case, then this command should succeed:
$ date -d 2037-01-01
Thu Jan 1 00:00:00 PST 2037
and this one should fail:
$ date -d 2039-01-01
date: invalid date ‘2039-01-01’
(I've reconstructed what the result should look like for that last command. The output of the first will vary slightly depending on your time zone.)
how to obtain the same behavior than BSD date, which accepts this as a valid date ?
Are you saying you want BSD date to reject it? If so (more speculation), either run a 32-bit version of BSD, or test whether the requested time is outside the 32-bit range of timestamps.
BSD date -d expects a time zone value. To offset years, days, or whatever, you pass -vNT, where N is a number and T is a char to indicate days, months, or years.
The flags differ. See http://www.unix.com/man-page/All/1/date/ for the Gnu version, http://www.unix.com/man-page/FreeBSD/1/date/ for a common BSD variant.

When does linux set the computer's correct time?

In a Linux CentOS 5 machine, I am running process.sh using a cronjob at #reboot, every day (the machine gets shut off every night and turned on every morning).
process.sh takes the 'date' of the computer, and writes it to a log file, then exits.
When I check the logfile, the timestamp in it says "Tue Jan 1 13:14:38 GMT 2008"
When I go to the console of the computer and give it the 'date' command, it prints the correct date.
My best guess is that my cronjob is running BEFORE the computer sets its correct time.
Is there a way to fix this?
The battery that powers the CMOS memory on your motherboard may have run out. Try replacing it by a fresh one. It should look something like this.
This advice is based on the fact that the date of your log entry is "Jan 1 2008" which looks conspicuously like an epoch your motherboard may use. However, the time-of-day 13:14:38 is a little off for this; while the 13 hour shift can be explained if you are in the correct time zone, the nearly 15 minute offset seems odd. Unless your computer takes that long to boot to the point where cron executes your job. And of course, the reason why you eventually see the correct time is probably that ntp fixed the system time, as others have noted.

dmesg -T results in inconsistent timestamp

This question is not related to the pause/resume issue!
For the same event 'dmesg' shows always the same time stamp, e.g.
[31765279.760248]
However when using 'dmesg -T', for the same event it shows slightly different seconds count, e.g. calling dmesg -T | grep something | tail -1 twice results in:
[Thu Jan 29 01:12:39 2015] event details...
[Thu Jan 29 01:12:38 2015] event details...
I need to compare events with history and act on new events. However this difference makes it impossible to use a simple string compare.
As a work around I clip the seconds from the strings before I compare them. I can do it in this case since the events I filter do not happen more than once in 5 minutes.
Does anyone know why this inaccuracy happens?
uname -a => Linux (hostname) 3.5.0-45-generic #68~precise1-Ubuntu SMP Wed Dec 4 16:18:46 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
Those timestamps are converted to real time by adding them to the system boot time. If the system came up at 1491516481.480856282 and you add a fractional offset to it, sometimes you'll see one extra full second.
Haven't checked the code but pretty certain that's the reason. There's a bit more information in Convert dmesg timestamp to custom date format including a response I wrote.

Why does the php 'date' function returns a wrong time (off by ~24 seconds)?

I have the following small php snippet running on a gentoo Linux (php version 5.2.10-pl0-gentoo):
#!/usr/bin/php5
<?
class TestDaemon {
public function __construct(){
while (TRUE){
unset($aDate);
exec("date", $aDate);
print("date(\"d.m.y H:i:s\") yields: ".date("d.m.y H:i:s")." while 'date' yields $aDate[0].\n");
sleep(1);
}
}
}
$oDaemon = new TestDaemon();
?>
And the output produced is as follows:
date("d.m.y H:i:s") yields: 27.03.14 07:05:27 while 'date' yields Thu Mar 27 07:05:03 UTC 2014.
date("d.m.y H:i:s") yields: 27.03.14 07:05:28 while 'date' yields Thu Mar 27 07:05:04 UTC 2014.
date("d.m.y H:i:s") yields: 27.03.14 07:05:29 while 'date' yields Thu Mar 27 07:05:05 UTC 2014.
date("d.m.y H:i:s") yields: 27.03.14 07:05:30 while 'date' yields Thu Mar 27 07:05:06 UTC 2014.
date("d.m.y H:i:s") yields: 27.03.14 07:05:32 while 'date' yields Thu Mar 27 07:05:07 UTC 2014.
date("d.m.y H:i:s") yields: 27.03.14 07:05:33 while 'date' yields Thu Mar 27 07:05:09 UTC 2014.
date("d.m.y H:i:s") yields: 27.03.14 07:05:34 while 'date' yields Thu Mar 27 07:05:10 UTC 2014.
date("d.m.y H:i:s") yields: 27.03.14 07:05:35 while 'date' yields Thu Mar 27 07:05:11 UTC 2014.
As you can see the times are off by approx. 24 seconds. On a different machine (same OS, same version of PHP) I do not see such an offset.
What is the reason for this offset? Does this come from leap second differences? Then which system gives the correct time? Why does php not use the Linux system time instead?
Also, can this time offset be a source of problems when working with the mysql database on the same system?
This looks like the shell running /bin/date is configured to use the "right" timezones and php is configured to use the POSIX-conformant timezones. The difference now should be 25 seconds, but if the tz data is over two years old then it would be 24 seconds. For a picture of why visit http://www.ucolick.org/~sla/leapsecs/amsci.html and see the second plot. The "right" zones follow the green line. The POSIX zones are required to stop the system clock on every leap second, so they follow the descending staircase of the blue line. [edit to be sure which was using which method]
Why the offset I don't know, but it seems that php date() uses time() function to get a timestamp. time() is defined like this:
Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT).
it never says in documentation that it uses System time.
According to this SO post the function time() uses the date.timezone set in php.ini or date_default_timezone_set().
So if your system uses a different time zone than your php.ini it could explain the difference because php seems to use its own time.
He also propose the following solution to get the real system time if they are not the same:
I'm going to give you a solution that works for Linux, I don't know for Windows. In Linux the system timezone is set in /etc/timezone.
Now, this is normally outside my allowed open_basedir setting, but you can add :/etc/timezone to your list to be able to read the file.
Then, on top of the scripts, that want to get the system time, you can call a library function that sets the script timezone to the system timezone. I suppose that this function is part of a class, so I use static:
static function setSystemTz() {
$systemTz = trim(file_get_contents("/etc/timezone"));
if ($systemTz == 'Etc/UTC') $systemTz = 'UTC';
date_default_timezone_set($systemTz);
}
To make the matter worse in PHP 5.3.3 'Etc/UTC' is not recognized, while 'UTC' is, so I had to add an if to fix that.
Not really answering your question but there are many different types of time variable on a typical Linux system:
The internal time of the harware clock (aka RTC or BIOS time), if you have one. This keeps the time when the system is offline, this may be fake and return bad values on a virtual machine, or you might not even have one. See hwclock
The amount of time that has passed since the kernel was started. (cat /proc/uptime)
The external time as provided by an NTP server via ntpd.
The innacuracy of the realtime clock / time source, how much it drifts over time in parts per million between samples. This is set by calls to the kernel. On a system with NTP it will be saved to your drift file (/var/lib/ntp/drift/ntp.drift or similar) and the system's time will be smoothly adjusted rather than have time jumps in your logs.
The number of miliseconds since 1st of January 1970. See date +%s
Your timezone, set in /etc/localtime, see zdump /etc/localtime
The current system time, calculated using all of the above plus rules for timezone, leap year, leap second and so on. See date
If I had to guess, I'd say that NTP is slowly adjusting your system time to compensate for your skewed realtime clock while PHP bypasses this and snags it from somewhere else.

linux uptime history

How can I get a history of uptimes for my debian box? After a reboot, I dont see an option for the uptime command to print a history of uptimes. If it matters, I would like to use these uptimes for graphing a page in php to show my webservers uptime lengths between boots.
Update:
Not sure if it is based on a length of time or if last gets reset on reboot but I only get the most recent boot timestamp with the last command. last -x also does not return any further info. Sounds like a script is my best bet.
Update:
Uptimed is the information I am looking for, not sure how to grep that info in code. Managing my own script for a db sounds like the best fit for an application.
Install uptimed. It does exactly what you want.
Edit:
You can apparantly include it in a PHP page as easily as this:
<? system("/usr/local/bin/uprecords -a -B"); ?>
Examples
the last command will give you the reboot times of the system. You could take the difference between each successive reboot and that should give the uptime of the machine.
update
1800 INFORMATION answer is a better solution.
You could create a simple script which runs uptime and dumps it to a file.
uptime >> uptime.log
Then set up a cron job for it.
Try this out:
last | grep reboot
according to last manual page:
The pseudo user reboot logs in each time the system is rebooted.
Thus last reboot will show a log of all reboots since the log file
was created.
so last column of #last reboot command gives you uptime history:
#last reboot
reboot system boot **************** Sat Sep 21 03:31 - 08:27 (1+04:56)
reboot system boot **************** Wed Aug 7 07:08 - 08:27 (46+01:19)
This isn't stored between boots, but The Uptimes Project is a third-party option to track it, with software for a range of platforms.
Another tool available on Debian is uptimed which tracks uptimes between boots.
I would create a cron job to run at the required resolution (say 10 minutes) by entering the following [on one single line - I've just separated it for formatting purposes] in your crontab (cron -l to list, cron -e to edit).
0,10,20,30,40,50 * * * *
/bin/echo $(/bin/date +\%Y-\%m-\%d) $(/usr/bin/uptime)
>>/tmp/uptime.hist 2>&1
This appends the date, time and uptime to the uptime.hist file every ten minutes while the machine is running. You can then examine this file manually to figure out the information or write a script to process it as you see fit.
Whenever the uptime reduces, there's been a reboot since the previous record. When there are large gaps between lines (i.e., more than the expected ten minutes), the machine's been down during that time.
This information is not normally saved. However, you can sign up for an online service that will do this for you. You just install a client that will send your uptime to the server every 5 minutes and the site will present you with a graph of your uptimes:
http://uptimes-project.org/
i dont think this information is saved between reboots.
if shutting down properly you could run a command on shutdown that saves the uptime, that way you could read it back after booting back up.
Or you can use tuptime https://sourceforge.net/projects/tuptime/ for a total uptime time.
You can use tuptime, a simple command for report the total uptime in linux keeping it betwwen reboots.
http://sourceforge.net/projects/tuptime/
Since I haven't found an answer here that would help retroactively, maybe this will help someone.
kern.log (depending on your distribution) should log a timestamp.
It will be something like:
2019-01-28T06:25:25.459477+00:00 someserver kernel: [44114473.614361] somemessage
"44114473.614361" represents seconds since last boot, from that you can calculate the uptime without having to install anything.
Nagios can make even very beautiful diagrams about this.
Use Syslog
For anyone coming here searching for their past uptime.
The solution of #1800_Information is a good advise for the future, but I needed to find information for my past uptimes on a specific date.
Therefore I used syslog to determine when that day the system was started (first log entry of that day) and when the system was shutdown again.
Boot time
To get the system start time grep for the month and day and show only the first lines:
sudo grep "May 28" /var/log/syslog* | head
Shutdown time
To get the system shutdown time grep for the month and day and show only the last few lines:
sudo grep "May 28" /var/log/syslog* | tail

Resources