1 #!/usr/bin/env ruby 2 3 ## 4 # A small application to change the title of an xterm to a meter with the 5 # current CPU usage (works only on Linux with a properly configured 6 # /proc) 7 # 8 9 ## 10 # Get the cpu info for the cpu with the given name. "cpu" is for all 11 # cpus, or cpu0 for the first cpu, etc. Returns: 12 # [ name, total_user, total_nice, total_system, total_idle ] 13 def get_cpuinfo(name = "cpu") 14 stats = File.readlines('/proc/stat') 15 begin 16 cpustat = stats[0].split(/\s+/) 17 end while cpustat[0] != name 18 return [ cpustat[0], *(cpustat[1..-1].map { |x| x.to_i }) ] 19 end 20 21 ## 22 # Given two return value from get_cpuinfo, return the difference between 23 # them. Returns: 24 # [ diff_user, diff_nice, diff_system, diff_idle ] 25 def cpudiff(oldcpuinfo, cpuinfo) 26 diff = [] 27 (1..4).each do |idx| 28 diff.push(cpuinfo[idx] - oldcpuinfo[idx]) 29 end 30 return diff 31 end 32 33 ## 34 # Run a loop that yields the difference in cpu usage since the last 35 # yield every interval seconds. 36 def cpu_stat_loop(name = "cpu", interval = 1) 37 oldcpuinfo = get_cpuinfo(name) 38 loop do 39 sleep interval 40 cpuinfo = get_cpuinfo(name) 41 diff = cpudiff(oldcpuinfo, cpuinfo) 42 yield diff 43 oldcpuinfo = cpuinfo 44 end 45 end 46 47 ## 48 # Return a string holding an ascii representation of a meter. 49 def ascii_meter(percent, total_bar_size) 50 bar_size = (total_bar_size * percent) 51 not_bar_size = (total_bar_size - bar_size) 52 return ('I' * bar_size) + (':' * (not_bar_size)) 53 end 54 55 ## 56 # Set the title of an xterm. 57 def set_xterm_title(x) 58 $stdout.print "\033]0;#{x}\007" 59 $stdout.flush 60 end 61 62 # Main 63 TOTAL_BAR_SIZE = 20 64 cpu_stat_loop do |diff| 65 total = (diff[0] + diff[1] + diff[2] + diff[3]) 66 idle_percent = diff[3].to_f / total 67 set_xterm_title( 68 ascii_meter(1.0 - idle_percent, TOTAL_BAR_SIZE) + 69 ' ' + 70 ("%2.1f" % (100.0 * (1.0 - idle_percent)))) 71 end