|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
The three rules of Ruby Quiz 2: 1. Please do not post any solutions or spoiler discussion for this quiz until 48 hours have passed from the time on this message. 2. Support Ruby Quiz 2 by submitting ideas as often as you can! (A permanent, new website is in the works for Ruby Quiz 2. Until then, please visit the temporary website at <http://splatbang.com/rubyquiz/>. 3. Enjoy! Suggestion: A [QUIZ] in the subject of emails about the problem s everyone on Ruby Talk follow the discussion. Please reply to the original quiz message, if you can. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ## Uptime Since... (#174) Nice and easy one this week. Your task is to write a Ruby script that reports the date and time of your last reboot, making use of the `uptime` command. While `uptime` is available on the various Unixes and Mac OS X, Windows users might need to do a little extra work. Here are [two][1] [options][2] for Windows users. [1]: http://support.microsoft.com/kb/555737 [2]: http://articles.techrepublic.com.com...1-5826014.html -- Matthew Moss <matthew.moss@gmail.com> |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
My own solution:
require 'date' (now, _, dd, _, _, dhm) = `uptime`.split(/ +|,/) (dd, dh, dm) = dd.to_i, *dhm.split(':').map { |x| x.to_i } dh += (dm / 60.0) dd += (dh / 24.0) last = DateTime.parse(now) - dd puts "Last reboot: #{last.year} #{Date::ABBR_MONTHNAMES[last.mon]} #{last.day} at #{last.hour}:#{last.min}" |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Sat, Aug 23, 2008 at 9:35 AM, Matthew Moss <matthew.moss@gmail.com> wrote:
> ## Uptime Since... (#174) > # A windows solution. require 'rubygems' require 'ruby-wmi' require 'date' str = WMI::Win32_OperatingSystem.find(:first).LastBootup Time boot = DateTime.strptime(str, "%Y%m%d%H%M") boot_date = boot.strftime("%Y %b") boot_time = boot.strftime("%I:%M") puts "Last reboot: #{boot_date} at #{boot_time}" |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
And my try at this:
coeff = [60,3600]; i = 0; offset = 0 s = %x{uptime} coeff.push 86400 if s =~ /day/ s.scan(/\d+/) do #I don't know how to stop scanning when I've had enough ^^;; |text| i = i + 1 offset = offset + text.to_i*(coeff.pop||0) if (3..5) === i end puts (Time.now - offset).strftime("System booted at %H:%M of %A, %B %d (%Y)") (I don't know anything about regexp, and it shows) -- Posted via http://www.ruby-forum.com/. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Sat, Aug 23, 2008 at 4:35 PM, Matthew Moss <matthew.moss@gmail.com> wrote:
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > > The three rules of Ruby Quiz 2: > > 1. Please do not post any solutions or spoiler discussion for this > quiz until 48 hours have passed from the time on this message. > > 2. Support Ruby Quiz 2 by submitting ideas as often as you can! (A > permanent, new website is in the works for Ruby Quiz 2. Until then, > please visit the temporary website at > > <http://splatbang.com/rubyquiz/>. > > 3. Enjoy! > > Suggestion: A [QUIZ] in the subject of emails about the problem > s everyone on Ruby Talk follow the discussion. Please reply to > the original quiz message, if you can. > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > > ## Uptime Since... (#174) > > > Nice and easy one this week. Your task is to write a Ruby script that > reports the date and time of your last reboot, making use of the > `uptime` command. My solution, tested in Ubuntu 8.04 and Fedora Core 2: uptime = (`uptime`.match /up (.*),.*user/)[1].delete(" ") captures = (uptime.match /((\d+)days,)?(\d+) \d+)/).captures[1..-1]elapsed_seconds = captures.zip([86440, 3600, 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}" Nice quiz !!! Jesus. |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Here's a one-liner using /proc/uptime:
puts Time.now - File.read('/proc/uptime').match(/^(\d+\.\d+) /)[1].to_f -- Jesse Merriman |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Aug 23, 8:35 am, "Matthew Moss" <matthew.m...@gmail.com> wrote: > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > > The three rules of Ruby Quiz 2: > > 1. Please do not post any solutions or spoiler discussion for this > quiz until 48 hours have passed from the time on this message. > > 2. Support Ruby Quiz 2 by submitting ideas as often as you can! (A > permanent, new website is in the works for Ruby Quiz 2. Until then, > please visit the temporary website at > > <http://splatbang.com/rubyquiz/>. > > 3. Enjoy! > > Suggestion: A [QUIZ] in the subject of emails about the problem > s everyone on Ruby Talk follow the discussion. Please reply to > the original quiz message, if you can. > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > > ## Uptime Since... (#174) > > Nice and easy one this week. Your task is to write a Ruby script that > reports the date and time of your last reboot, making use of the > `uptime` command. require 'sys/uptime' p Sys::Uptime.uptime > ![]() Regards, Dan PS - No parsing involved. Uses sysctl/times/wmi, depending on platform. |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Matthew Moss wrote:
> Nice and easy one this week. Your task is to write a Ruby script that > reports the date and time of your last reboot, making use of the > `uptime` command. > > While `uptime` is available on the various Unixes and Mac OS X, > Windows users might need to do a little extra work. Here are [two][1] > [options][2] for Windows users. last | grep reboot | head -1 Am I doing it right? :P -Erik -- Posted via http://www.ruby-forum.com/. |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
On Mon, Aug 25, 2008 at 6:12 PM, Erik Hollensbe <erik@hollensbe.org> wrote:
> Matthew Moss wrote: > >> Nice and easy one this week. Your task is to write a Ruby script that >> reports the date and time of your last reboot, making use of the >> `uptime` command. >> >> While `uptime` is available on the various Unixes and Mac OS X, >> Windows users might need to do a little extra work. Here are [two][1] >> [options][2] for Windows users. > > last | grep reboot | head -1 > > Am I doing it right? :P > This works for me on OS X. require 'time' Time.parse `last | tail -1` Michael Guterl |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
Matthew Moss wrote:
> Nice and easy one this week. Your task is to write a Ruby script that > reports the date and time of your last reboot, making use of the > `uptime` command. Why use `uptime` when there's `who -b`? Here is my solution. It should run out of the box (i.e. no gems needed) on all major platforms. --- require 'time' methods = [ lambda { # Windows require 'Win32API' getTickCount = Win32API.new("kernel32", "GetTickCount", nil, 'L') Time.now - getTickCount.call() / 1000.0 }, lambda { # *BSD, including Mac OS Time.at(`sysctl -b kern.boottime 2>/dev/null`.unpack('L').first) }, lambda { # Some other form of *nix Time.parse(`who -b 2>/dev/null`) } ] begin unless methods.empty? boot_time = methods.shift.call else puts "Unable to determine time of last reboot. Sorry!" exit!(1) end rescue Exception retry end puts "Last reboot: #{boot_time.asctime}" --- Regards, Matthias -- Posted via http://www.ruby-forum.com/. |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
On Mon, Aug 25, 2008 at 7:30 PM, Jes=FAs Gabriel y Gal=E1n
<jgabrielygalan@gmail.com> wrote: > On Sat, Aug 23, 2008 at 4:35 PM, Matthew Moss <matthew.moss@gmail.com> wr= ote: >> ## Uptime Since... (#174) >> >> >> Nice and easy one this week. Your task is to write a Ruby script that >> reports the date and time of your last reboot, making use of the >> `uptime` command. > > My solution, tested in Ubuntu 8.04 and Fedora Core 2: > > uptime =3D (`uptime`.match /up (.*),.*user/)[1].delete(" ") > captures =3D (uptime.match /((\d+)days,)?(\d+) \d+)/).captures[1..-1]> elapsed_seconds =3D captures.zip([86440, 3600, 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}" I realized that there was a case I wasn't taking into account: a machine bo= oted less than 1 hour ago. So here is my revised solution, also compacting a lit= tle bit things, using only one regexp: captures =3D (`uptime`.match /up (? ? \d+) days,)?\s+(\d+) \d+)|(\d+)min)/).captures elapsed_seconds =3D captures.zip([86440, 3600, 60, 60]).inject(0) do |total, (x,y)| =09total + (x.nil? ? 0 : x.to_i * y) end puts "Last reboot was on #{Time.now - elapsed_seconds}" Anybody knows what's the format for a machine that's been up more than a day, but less than two? Is it "up 1 day" or "up 1 days"? Anyway I'm thinking changing that part of the regexp to "day(?:s)?" should suffice to take into account both cases, but I can't test it right n= ow. Jesus. |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
Jesús Gabriel y Galán wrote:
> I realized that there was a case I wasn't taking into account: a machine > booted > less than 1 hour ago. And I missed the case of an uptime between 24 and 25 hours. (On OSX, at least). Which makes my solution fail quite badly in that time bracket. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
Le 23 août 2008 à 16:35, Matthew Moss a écrit :
A solution tested with windows uptime.exe, FreeBSD and Linux. It should work with most of the others and in most of the edge cases, I think. #! /usr/local/bin/ruby def startup(t) u = (t.downcase.match(/up(.*?)(?:\d+ user.*)?$/)[1]) lu = u.split(/([0-9:]+)/).map { |e| e.strip.gsub(/,/, '') }.reject { |e| e == '' } count = 0 lu.each_index do |i| count += case lu[i] when /(\d+) \d+)(?: \d+))?/$1.to_i * 3600 + $2.to_i * 60 + ($3 ? $3.to_i : 0) when /(\d+)/ n = lu[i].to_i case lu[i + 1] when nil then raise "Unknown format" when /^day/ then n * 86400 when /^hour/ then n * 3600 when /^min/ then n * 60 when /^sec/ then n else raise "Unknown modifier (#{lu[i + 1]})" end else 0 end end Time.now - count end [ `uptime`, '11:40:08 up 15 days, 16:08, 1 user,2 load average: 0.06, 0.04, 0.01', '\\LAPHROAIG has been up for: 25 day(s), 13 hour(s), 46 minute(s), 10 second(s)' ].each { |c| puts startup(c).strftime('%c') } 12:09 fred@balvenie:~/ruby> ./uptime.rb Wed Jun 25 07:05:41 2008 Sun Aug 10 20:01:41 2008 Thu Jul 31 22:23:31 2008 Fred -- Tried to save a place from the cuts and the scratches Tried to overcome the complications and the catches Nothing ever grows and the sun doesn't shine all day (Nine Inch Nails, Tried to save myself but myself keeps slipping away Into the Void) |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
Jesús Gabriel y Galán wrote:
> Anybody knows what's the format for a machine that's been up more than > a day, but less than two? > Is it "up 1 day" or "up 1 days"? Anyway I'm thinking changing that > part of the regexp to "day(?:s)?" > should suffice to take into account both cases, but I can't test it > right now. On the machines I know (several *nixes) it is neither "up 1 day" nor "up 1 days", but "up 1 day(s)". To make matters worse some versions of `uptime` yield a localized message: --- 1:49pm in Betrieb 6 Tag(e), 9:12, 12 Benutzer, Durchschnittslast: 3,11, 3,13, 3,19 --- Maybe a more general approach is needed to account for these corner cases. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
On Aug 25, 11:20=A0pm, Matthias Reitinger <reiti...@in.tum.de> wrote: > Matthew Moss wrote: > > Nice and easy one this week. Your task is to write a Ruby script that > > reports the date and time of your last reboot, making use of =A0the > > `uptime` command. > > Why use `uptime` when there's `who -b`? Because `uptime` is what I requested... ![]() Sometimes it's not about the final result, but about the process. |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
Matthew Moss wrote:
> On Aug 25, 11:20�pm, Matthias Reitinger <reiti...@in.tum.de> wrote: >> Matthew Moss wrote: >> > Nice and easy one this week. Your task is to write a Ruby script that >> > reports the date and time of your last reboot, making use of �the >> > `uptime` command. >> >> Why use `uptime` when there's `who -b`? > > Because `uptime` is what I requested... ![]() > > Sometimes it's not about the final result, but about the process. Yep, this is a "count backwards in time" exercise slightly obfuscated. My "solution" was a bit of a joke, and I apologize for the mess I've caused. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
Matthew Moss wrote:
> On Aug 25, 11:20�pm, Matthias Reitinger <reiti...@in.tum.de> wrote: >> Matthew Moss wrote: >> > Nice and easy one this week. Your task is to write a Ruby script that >> > reports the date and time of your last reboot, making use of �the >> > `uptime` command. >> >> Why use `uptime` when there's `who -b`? > > Because `uptime` is what I requested... ![]() > > Sometimes it's not about the final result, but about the process. I know, I know. I guess I just wanted to make my life a bit easier there ![]() -- Posted via http://www.ruby-forum.com/. |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
On Aug 26, 10:44=A0am, Matthias Reitinger <reiti...@in.tum.de> wrote: > Matthew Moss wrote: > > On Aug 25, 11:20 pm, Matthias Reitinger <reiti...@in.tum.de> wrote: > >> Matthew Moss wrote: > >> > Nice and easy one this week. Your task is to write a Ruby script tha= t > >> > reports the date and time of your last reboot, making use of the > >> > `uptime` command. > > >> Why use `uptime` when there's `who -b`? > > > Because `uptime` is what I requested... =A0 ![]() > > > Sometimes it's not about the final result, but about the process. > > I know, I know. =A0I guess I just wanted to make my life a bit easier > there ![]() No worries. I'm not deducting any points this week. ![]() |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
On 8/23/08, Matthew Moss <matthew.moss@gmail.com> wrote:
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > ## Uptime Since... (#174) > > Nice and easy one this week. Your task is to write a Ruby script that > reports the date and time of your last reboot, making use of the > `uptime` command. > Here's my Windows solution. I offer it as an object lesson about why you should always check the built-in library documentation first. I knew that Windows could report the dates in several different formats based on user settings. I wanted to be able to handle all of them, so I rolled my own parser based on checking the registry to see what format to expect. Then I discovered Time#parse.... -Adam ########################## ## Windows-uptime.rb ## Ruby Quiz # ## -Adam Shelly ## (The hard way) #find out what form windows is going to report the date in dateform = `reg query "HKCU\\Control Panel\\International" /v sShortDate`.chomp dateform = /REG_SZ\t(.*)$/m.match(dateform)[1].chomp timeform = `reg query "HKCU\\Control Panel\\International" /v sTimeFormat`.chomp timeform = /REG_SZ\t(.*)$/m.match(timeform)[1].chomp timeform.gsub!(/:[sS]+/,'') is_PM = `reg query "HKCU\\Control Panel\\International" /v s2359`.chomp is_PM = /REG_SZ\t(.*)$/m.match(is_PM)[1].chomp #these are the format characters it may use (sorted in descending order by size: year -> minute) $special="yYmMdDhHmMtT" #build a regexp that matches the format string, # record which order the result groups are returned in # Assumes that there is sone separator character # won't work if the format is something like DDMMYY def buildQuery formatstr, indexes idx=1 formatstr.each_byte{|b| if $special.include?(b.chr) indexes[b.chr.upcase]=idx else idx+=1 end } #replace all the format chars with word matchers f = formatstr.gsub(Regexp.new("[#{$special}]"),'\w') #make groups f = f.gsub(/(\\w)+/,'(\w+)') return f end #storage for regexp group indexes dateidx,timeidx={},{} #build regexp to match result regexp = Regexp.new "since "+buildQuery(dateform, dateidx)+' '+buildQuery(timeform, timeidx) #since we are combining 2 regexps, the second set of groups are offset by the number of groups in the first timeidx.each_key{|k| timeidx[k]+=dateidx.values.max} #do the match datematch = regexp.match(`net stats srv`) a=[] idxset=dateidx #build an array with the results of the match, in descending order, $special.upcase.squeeze.each_byte{|b| idxset = timeidx if b==?H #switch to time indexes when we get to Hours a<<datematch[idxset[b.chr]] } #add 12 if string contains this locale's version of 'PM' a[3]=a[3].to_i+12 if datematch[timeidx['T']]==is_PM #convert month names to integers, if needed # ??Question: Does strftime return names in the current locale?? (1..12).each{|m| a[1]=m if datematch[dateidx['M']].include?(Time.utc(0,m).strftime("%b")) } #construct the start time, calculate seconds elapsed until now starttime = Time.local(*a) s=(Time.now-starttime).to_i; #show results print datematch[0].gsub("since", "Last reboot at") puts ".\n #{s} seconds ago." #expand seconds into normalized units. (Is there a library function to do this?) puts 'uptime = '+ [['%d seconds',60],['%d minutes',60],['%d hours',24],['%d days',365],['%d years',1000]].map{|w,v| s,rem=s.divmod v; w%rem if rem>0 }.compact.reverse*' ' #################################### ## Now, the Easy way require 'Time' datematch = /since (.*)$/.match(`net stats srv`) s= Time.now - Time.parse(datematch[1]) print "\n"+datematch[0].gsub("since", "Last reboot at") puts ".\n #{s.to_i} seconds ago." puts "uptime = %.2f days."%[s/(60*60*24.0)] |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
> require 'sys/uptime'
> p Sys::Uptime.uptime I installed rb-sys-uptime on Mac OS X, couldn't get this to work. It recognizes Sys::Uptime, but when I try to call method 'uptime', I get: "Sys::UptimeError: failed to extract uptime" |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
> This works for me on OS X.
> > require 'time' > Time.parse `last | tail -1` That doesn't come close to working for me on OSX. There are many more timestamps in that file than just the reboots. The version Erik provided works correctly. |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
On Thu, Aug 28, 2008 at 11:01 AM, Matthew Moss <matthew.moss@gmail.com> wrote:
>> This works for me on OS X. >> >> require 'time' >> Time.parse `last | tail -1` > > That doesn't come close to working for me on OSX. There are many more > timestamps in that file than just the reboots. The version Erik > provided works correctly. > FWIW, `last | grep reboot` returns nothing for me on my MacBook. |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
On Thu, Aug 28, 2008 at 11:31 AM, Michael Guterl <mguterl@gmail.com> wrote:
> On Thu, Aug 28, 2008 at 11:01 AM, Matthew Moss <matthew.moss@gmail.com> wrote: >>> This works for me on OS X. >>> >>> require 'time' >>> Time.parse `last | tail -1` >> >> That doesn't come close to working for me on OSX. There are many more >> timestamps in that file than just the reboots. The version Erik >> provided works correctly. >> > > FWIW, `last | grep reboot` returns nothing for me on my MacBook. > Doh, clicked send too quickly. Also, you're right, my version doesn't seem to be working right either... |
|
![]() |
| Outils de la discussion | |
|
|