Python: Uptime script

I’ve been writing Python for a grand total of 2 days. I recently wrote a little Python script to print a Linx or UNIX system’s uptime. This took about 10 minutes to write, so I was pretty pleased. It even runs well on a 75MHz Busybox embedded Linux system. Check it out:

#!/usr/bin/python
import os

#----------------------------------------
# Gives a human-readable uptime string
def uptime():

     try:
         f = open( "/proc/uptime" )
         contents = f.read().split()
         f.close()
     except:
        return "Cannot open uptime file: /proc/uptime"

     total_seconds = float(contents[0])

     # Helper vars:
     MINUTE  = 60
     HOUR    = MINUTE * 60
     DAY     = HOUR * 24

     # Get the days, hours, etc:
     days    = int( total_seconds / DAY )
     hours   = int( ( total_seconds % DAY ) / HOUR )
     minutes = int( ( total_seconds % HOUR ) / MINUTE )
     seconds = int( total_seconds % MINUTE )

     # Build up the pretty string (like this: "N days, N hours, N minutes, N seconds")
     string = ""
     if days > 0:
         string += str(days) + " " + (days == 1 and "day" or "days" ) + ", "
     if len(string) > 0 or hours > 0:
         string += str(hours) + " " + (hours == 1 and "hour" or "hours" ) + ", "
     if len(string) > 0 or minutes > 0:
         string += str(minutes) + " " + (minutes == 1 and "minute" or "minutes" ) + ", "
     string += str(seconds) + " " + (seconds == 1 and "second" or "seconds" )

     return string;

print "The system uptime is:", uptime()

One interesting thing about this script is its emulation of the C ternary operator using Python’s short-circuited “and” operator. Notice this bit:

(days == 1 and "day" or "days" ) 

Python doesn’t have the C-style ternary operator:

(days == 1 ? "day" : "days")

So the short-circuited “and” is a decent alternative. Instead of ignorantly printing “1 days”, this code will actually print “1 day” and “2 days” like it should.

17 comments to “Python: Uptime script”

You can leave a reply or Trackback this post.
  1. http://Jesse says: -#1

    Nice script! I am going to use it in a script I am writing for my backup server at home (open Source of course). You saved me a lot of time.

  2. Thanks for the nice hack with ternary operator, I was searching for it for a while now.
    The script is nice to, though you might mention that, in order to be able to call it “uptime” instead of “python uptime” a line “#!/path/to/python/interpreter” should be added (it also took me a while to figure this out in the beginning).

  3. This was meant as an example code snippet that others could use in their Python programs, not as a stand-alone script. For that purpose, I would just use the “uptime” command.

    –Dave

  4. http://Friedmud says: -#1

    Thanks for the idea… I was just getting ready to call “uptime” via ssh to get the load average on a bunch of machines…. but after seeing this script I noticed that all I have to do is something like:

    file = os.popen(‘ssh machine_name “cat /proc/loadavg”‘)
    contents = file.read().split()
    print contents[0]

    Which is much easier!

    Friedmud

  5. http://Robert says: -#1

    That works for Linux but not for Unix, as they do not publish relevant system information in /proc.

  6. The ternary operator is nice, but detrimental to readability. You can substitute:

    string += str(days) + ” ” + (days == 1 and “day” or “days” )

    with the more readable (and equally short):

    string += str(days) + ‘ day’
    if days > 1: string += ‘s’

  7. What about the case of 0 days? Your code will show “0 day”, but I would prefer “0 days”.

    I think the version with the ternary operator is actually more readable than two separate lines.

  8. http://trash80 says: -#1

    Great script. Nice to see others that also prefer readable code over obfuscated, complex one liners. I’m not big on ternaries, but this seems alright. Thanks for the script.

  9. http://Zemair says: -#1

    (sorry my bad english)

    Hi Dave! Great script! Thanks for the code!

    I want contribute! To work on FreeBSD 6.x and FreeBSD 7.x, replace lines 9, 10, 11 and 13 with follow lines:

    [line 9] varOutPut = commands.getoutput(“/sbin/sysctl kern.boottime | /usr/bin/awk ‘{ print $5 \”.\” $8 }'”)

    [line 10] varOutPut = varOutPut.split(“,”)

    [line 11] total_seconds = time.time() – float(varOutPut[0])

    [line 13] “Cannot request kernel variable”

    Also import “commands” to proper work the getoutput method.

  10. http://Tim says: -#1

    Brilliant little script – thanks!

    Despite your earlier comment, I think this is useful as a stand-alone script. The problem with the ‘uptime’ command is that is outputs other junk as well as the system uptime, and because this output is so variable depending on how long the system has been up, parsing it to extract only the uptime is non-trivial.

    If you want just the system uptime, and nothing more, your script does the business!

  11. http://Anonymous says: -#1

    Hello Dave,

    Your script is really very usefull, but I refactored it. I used datetime lib to simplify handle with time.

    Here is the result: http://pastebin.com/Tks3Rnst

    Anyway thanks for the inspiration ;-)

  12. Hello Dave,

    Your script is really very usefull, but I refactored it. I used datetime lib to simplify handle with time.

    Here is the result: http://pastebin.com/Tks3Rnst

    Anyway thanks for the inspiration ;-)

    Greeting from Brazil!!

  13. http://Squeezemynutz says: -#1

    @Mauro Baraldi: Script does not display the day correctly, on my Debian box it’s had an uptime of 66 days, your script says 6.

  14. http://Aryeh%20Leib%20Taurog says: -#1

    @Mauro don’t use fromtimestamp, because that is a calendar date which starts at 2am 1970-01-01 and wraps back around to 1 at the beginning of each month, so your day and your hour will always be off.

    All we really need is:

    import datetime
    with open(‘/proc/uptime’) as f:
    uptime, idletime = map(float, f.read().split())

    print(datetime.timedelta(seconds=uptime))

    @Dave python does have a ternary operator
    http://docs.python.org/reference/expressions.html#conditional-expressions

  15. Aryeh, thanks for the info. Cool news about the new ternary operator in Python 2.5.

  16. http://Vinod says: -#1

    You mean, when i paste this code to IDLE and run this code, it will show me my system up time. Am i right ?

  17. Vinod, yes, if you are on Linux. Won’t work on Windows.