[SUMMARY] Uptime Since... (#174)

Discussion in 'Ruby' started by Matthew Moss, Aug 28, 2008.

  1. Matthew Moss

    Matthew Moss Guest

    First thing: the quiz name is off. Really, it should properly have
    been called "Up Since...", as we're looking for the time of reboot.
    The `uptime` command was in my mind, though, which is why the title is
    strange.

    There are a number of ways to attack this problem, as shown in the
    variety of the solutions. First, let's look at "the right way" to
    solve this problem: use a library or module that does the work for
    you. Such was _Daniel Berger_'s solution, shown here:

    require 'sys/uptime'
    p Sys::Uptime.uptime

    Unfortunately, this didn't work on my machine, and hopefully that's
    only because of an outdated version of rb-sys-uptime, or some similar
    reason. I'll take Daniel's word that this works on his, though I
    wonder whether he's returning the uptime or the time of last reboot
    (as requested). Still, with such a module that abstracts the platform
    differences, this is an easy win... if you get it to work. (Offhand,
    this seems to be a Darwin, i.e. Mac OS X, module; if true, then it's
    not "the right way" for other platforms.)

    Let's go on to the submission from _Erik Hollensbe_, which isn't even Ruby code.

    last | grep reboot | head -1

    Sometimes the Unix way is the best way. Of course, you need to know
    where this information resides, and there may still be platform
    differences (along with significant command-line differences on
    Windows), but this is a simple and quick one-liner that requires only
    a few common tools.

    Let's look now at some Ruby code. We'll look first at _Jesus
    Gabriel_'s second submission:

    captures = (`uptime`.match /up (?:(?:(\d+)
    days,)?\s+(\d+):(\d+)|(\d+) min)/).captures
    elapsed_seconds = captures.zip([86440, 3600, 60, 60]).inject(0) do
    |total, (x,y)|
    total + (x.nil? ? 0 : x.to_i * y)
    end
    puts "Last reboot was on #{Time.now - elapsed_seconds}"

    The uptime information is gathered from the call to `uptime`. Note the
    backticks, which indicate that this is a shell command to be executed,
    and its output returned. The output is matched against a regular
    expression, containing a number of groups, several of which are
    optional. Four of those groups, however, are returned, to match
    against days, hours or minutes passed. (The minutes may be grouped in
    one of two ways.)

    The captured results are paired up with the array `[86440, 3600, 60,
    60]`, each entry corresponding to the number of seconds in a day, hour
    or minute. Finally, using inject, the total number of seconds since
    the last reboot is determined. Subtracting this from `Time.now`
    results in the time of the last reboot.

    A few comments... As was mentioned on the mailing list, the regular
    expression to match the output of `uptime` is fragile. A few
    variations were shown to exist. A more complex regular expression
    might be able to capture more variants, though the better answer is
    not to call `uptime` as a shell command, but rather use the
    appropriate system services to access the information directly.
    However, all this parsing is a direct result of my asking for it, so
    for this quiz, I'm not too concerned about this problem.

    What I found a bit interesting (or confusing) was the different
    classes available for date/time information: `Date`, `Time` and
    `DateTime`. My own solution used `DateTime`, which I wrongly assumed I
    would need (thinking `Time` was only time information). I should have
    explored more, since the `Time` solution seems simpler.

    Additionally, one subtracts _days_ from `DateTime` objects, but
    subtracts _seconds_ from `Time` objects. `Time` supports a `now`
    method, while `DateTime` does not. I expect there is some amount of
    logic to these classes, but it seems to have escaped me this time
    around.

    One last comment on Jesus' solution. The `uptime` shell command
    provides the current time simultaneously with the elapsed time since
    last reboot. Yet his solution uses `Time.now` rather than the provide
    time. For this quiz, it's not big thing: the answer would, at most, be
    off by one minute. Still, it may be an important consideration for
    other scripts to preserve the matching time, to ensure accuracy.

    Make sure to take a look at the other solutions. In particular, the
    Windows solution from _Gordon Thiesfeld_ which makes use of an
    operating system module to get the last reboot time directly. Also,
    from _Jesse Merriman_ is a solution that access the process file
    system.




    --
    Matthew Moss <>
     
    Matthew Moss, Aug 28, 2008
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Oli Schwarz

    uptime in unix

    Oli Schwarz, Sep 19, 2004, in forum: Python
    Replies:
    8
    Views:
    4,550
    Heiko Wundram
    Sep 20, 2004
  2. Esmail Bonakdarian

    uptime for Win XP?

    Esmail Bonakdarian, Dec 11, 2004, in forum: Python
    Replies:
    24
    Views:
    12,419
    Peter Hansen
    Dec 13, 2004
  3. Andrey Ivanov

    Re: uptime for Win XP?

    Andrey Ivanov, Dec 12, 2004, in forum: Python
    Replies:
    0
    Views:
    449
    Andrey Ivanov
    Dec 12, 2004
  4. Gully Foyle
    Replies:
    0
    Views:
    88
    Gully Foyle
    Jul 22, 2004
  5. Matthew Moss

    [QUIZ] Uptime Since... (#174)

    Matthew Moss, Aug 23, 2008, in forum: Ruby
    Replies:
    24
    Views:
    231
    Michael Guterl
    Aug 28, 2008
Loading...

Share This Page