blog advertising is good for you


blog advertising is good for you
User login

Geektool and Bash One-Liners

So there’s a Tiger compatible version of GeekTool floating around finally, and I’ve been playing around with it the past couple days.

I’m still a beginner at shell scripting and the whole gestalt of modern computing, and I’ve found this not only fun to play with, but also quite educational, especially with regards to those geekiest of tools, bash one-liners.

I’ve learned a lot from this, for instance that I like awk. It certainly isn’t awkward, lol. And take away my propensity for just doing cool crap because I can, and this thing can still be really quite actually real-world useful. It’s already replaced half my Dashboard — I find the displayed information simultaneously more noticible and less in the way.

So I thought I’d write down my setup, and some other stuff I found that works nice with GeekTool even if it might not maybe be all that actually useful all the time. And some links to the work of others.

My Dealy

Here’s what I got on my desktop right now:

  • The next few events on my iCal
  • a list of (fairly interesting) running processes
  • the number of unread items in my Bloglines
  • uptime
  • memory and cpu usage
  • my local ip
  • my external ip and hostname
  • a calendar

I also have separate group that displays the latest satellite weather maps. Sweet.

iCal events

This is actually pretty involved. I published a calender in iCal to my website, then used a php script to grab and format the information i want out of it, then used:

/sw/bin/lynx -dump http://cutup.org/ical.php

to display it. The -dump option just has lynx dump whatevers in the page to the Terminal. I have it set to refresh every 3600 seconds (1 hour). As the newness wears off, and considering how often my iCal changes this may go down significantly. Note the full path to lynx, it seems to need that even though it’s in my $PATH. I’m sure you could use curl for this too, but I haven’t tried it for this.

Processes

There’s a few ways to run this. Right now, I like:

ps -cm -U username | awk ‘/:/ && $5!~/Dashboard/’

c omits the full path of each process, m orders the processes by memory and -U username shows all processes owned by that user. Plain ps only shows processes run through the terminal, ps -A gives me more than I want to see, ps -U was pretty good, I thought. Replacing the m with r orders the processes by CPU usage, I haven’t really decided which one I like better.

The awk command /:/ strips out the top line that names the fields – it says only print lines that include a colon. && (and) do not capture lines where field 5 does not contain the string “Dashboard” (I dunno — it was annoying me for some reason to see them).

I have this refreshing every 10 seconds. What can I say? I like seeing the numbers change.

Bloglines Unread Items

While snooping around in the Bloglines API I found a nice url that returns, very simply, the number of unread items in your account. So:

/sw/bin/lynx -dump http://rpc.bloglines.com/update?user=username@address.com&ver=1 gives you a nice little count. I have this set to refresh every 300 seconds (5 minutes).

Uptime, Memory, and CPU Use

I managed to fit all this into a one-liner. I was so proud I left it that way, even though I like refreshing my memory and cpu stats every 10 seconds, and uptime doesn’t really need to be updated that often. But what the hell, I have a modern laptop computer, well capable of this sort of frippery. I still wonder which is more intensive, having two separate tasks that refresh at different intervals, or one task that doesn’t refresh as efficiently as possible. I have no idea where to even start trying to figure that out.

So anyway, I’m running:

uptime | awk ‘{printf “up : “ $3 “ “ $4 “ “ $5 “ “ }’; top -l 1 | awk ‘/PhysMem/ {printf “RAM : “ $8 “, }’ ; top -l 2 | awk ‘/CPU usage/ && NR > 5 {print $6, $7=, $8, $9=“user”, $10, $11=“sys”, $12, $13}’

Ooh, exciting, eh? Basically, using printf instead of print makes it so awk doesn’t carriage return after it outputs, allowing this all to go on one very spiffy line at the bottom of my screen.

I have uptime piped into awk and discarding everything but field 3. Then there’s some slightly strange calls to top to get the CPU and memory stats. Geektool can’t deal with interactive proccesses like top, but top allows us to dump snapshots instead, with the -l flag. So top -l 1 outputs one snapshot of top. Geektool is cool with that, and then it’s a simple matter of piping the output to awk and printing the applicable field, formatted nicely of course since we’re using printf.

For CPU use it’s a bit trickier. For some reason top -l 1 prints an inaccurate reading. But oddly enough, if you use top -l 2 you get two readings, and the second one is accurate! I still had to bash my head against this for a while to figure out how to only print the second line. All the parts that don’t change are identical, so I couldn’t easily use awk as a filter.

After much man awk and search engineering I found out about NR, which seems to be awk for line number. When I told awk to print NR’s on each line, I noticed that the first line was always a very low number (actually it seemed to always be 2), and the second line was always a high number (in the 80’s), so I was able to tell awk && NR > 5 and it works great so far. With this and the ip stuff that comes next I was able to retire my SystemStats dashboard widget.

Awk is cool. I found it pretty easy to get started with, simple and useful for lots of everyday grepping type stuff. I learned lots of good stuff about it pretty quickly here and here. The more comfortable I get with stuff like this, the more the 1970’s era technology of UNIX appeals to the futurist in me.

Local IP

I tried to combine this with the external IP but even with awk and printf I was getting a line break so for now they’re separate. It goes:

ifconfig | awk ‘/broadcast/ {print $2}’

which is field 2 from the line containing “broadcast” in ifconfig. I have this refreshing every 120 seconds.

External IP

I’m sure there’s a better way but here’s how I do it. I have a php script on my server that displays the IP adress of whoever hits it. And I have a script in the webserver part of my local machine that calls it. The script looks like this:

if ($ip = @file_get_contents("http://cutup.org/ip.php")) { $host = gethostbyaddr($ip); print "$ip $host"; } else { print "no net connection?"; }

It gets the external IP from my ip printing page and also does a host lookup. So then:

/sw/bin/lynx -dump http://localhost/~username/loc.php tells me where my computer is. I like how this is web accessible, so if I can access my server remotely I can see where it is Smiling You never know, it might come in handy some day. I have this set to refresh every 120 seconds as well.

Calendar

This one’s simple. All it is:

cal

There’s some interesting ideas for cal and Geektool I haven’t tested yet at macosxhints, but for now this is good for me.

Weather

Geektool can display pictures from a URL. So the trick is to find JPEGs online that are refreshed every so often and where the name of the file does not change. I found a bunch at weather.com and some more at uswx.com. Right now I have a group, separate from all the other stuff, that has three pictures running:

US Visible Satellite

Northeast Infrared Satellite

World Satellite

There’s still room for more, but for now this replaces my US Weather dashboard widget nicely. Notice that you call tell from the picture urls that the filename is not likely to change. If there’s a date or time in the name of the picture, this wouldn’t be so easy.

Stuff I Had to Figure Out

By default, Geek Tool windows are black text. My backgrounds are usually dark, so I have to change the text color to white before I can even see anything there. I wouldn’t mention it except that I couldn’t figure out whether my command wasn’t working or the display was wierd when I got started.

Other Stuff That May Be of Interest

I picked this up somewhere, it seems to show all the connections on your network

netstat -ab -f inet | grep -i established | sort +4

This one’s neat. It shows the IP’s of everyone that visited your site:

tail -5000 /var/log/httpd/access_log | grep -v 127.0.0.1 | awk ‘{print $1}’ | uniq

Or even:

tail -5000 /var/log/httpd/access_log | grep -v 127.0.0.1 | awk ‘{print $1}’ | uniq | nslookup -silent | awk ‘/name = /’

which gives you their hostname. I’m not clear on how to translate this information into a more useful domain name; when I do I imagine I will probably end up using this a lot.

Resources

macoshints search for “geek tool”

I originally wrote this here, and then the MacGeekery feed told me I should post it here. Smiling

[Ed: Edited to match site style.]

Average rating
(0 votes)
About 31d1

Author Biography

He starts his first programming job next week.

>For CPU use it’s a bit trickier. For some reason top -l 1 prints an inaccurate reading. But oddly enough, if you use top -l 2 you get two readings, and the second one is accurate! I still had to bash my head against this for a while to figure out how to only print the second line.

tail -1
(or tail -n 1)

I’ve posted a GeekTool recipe on my blog which will show the ping time to a particular host. I have two of them configured, one pinging my server at home, the other pinging my hosted website. It only pings every 20 seconds, but it’s quite handy for spotting things like my home ADSL connection going down.

Do you know if anyone has figured out a way to pull info from a Google Analytics account?

Thanks for the tips

If you like that netstat command, you might like lsof -i tcp -i udp

This is my very first post to any online blog. I am new to mac and scripting. I am really impressed with the Geektool considering the possibilities it has. I used the network script available on some blog but was not happy with the lengthy output so went through the script understanding wat was happening, then thought of creating my first script with trial and error method. This is my script:
================================================================
myen0=‘ifconfig en0 | grep “inet “ | grep -v 127.0.0.1 | awk ‘{print $2}’‘
myen1=‘ifconfig en1 | grep “inet “ | grep -v 127.0.0.1 | awk ‘{print $2}’‘
myvar1=‘system_profiler SPAirPortDataType | grep -e “Current Wireless Network:” | awk ‘{print $4}’‘
myvar2=‘system_profiler SPAirPortDataType | grep -e “Wireless Channel:” | awk ‘{print $3}’‘
router=‘netstat -rn | grep -e “default” | awk ‘{print $2}’‘
ext1=‘curl -s http://checkip.dyndns.org/ | sed ‘s/[a-zA-Z<>/ :]//g’‘
dns=‘cat /etc/resolv.conf | grep -e “nameserver” | awk ‘{print $2}’‘
isp1=‘whois -h whois.apnic.net $ext1 | grep -e “netname:” | awk ‘{print $2}’‘
if [ “$myen0” != “” ]
then if [ “$myen1” != “” ] then echo “Connection : Ethernet | Airport [$myvar1 : $myvar2]” echo “IP Address : $myen0 | $myen1” else echo “Connection : Ethernet” echo “IP Address : $myen0” fi
else if [ “$myen1” != “” ] then echo “Connection : Airport [$myvar1 : $myvar2]” echo “IP Address : $myen1” else echo “Connection : No Network” echo “IP Address : No Network” fi
fi
echo “Router : $router”
if [ “$router = “$dns ]
then echo “DNS Servers: No DNS Detected”
else dns=‘system_profiler SPNetworkDataType | grep -e “Server Addresses: “ | awk ‘{print $3, $4}’‘ echo “DNS Servers: $dns”
fi
echo “External : $ext1”
echo “ISP : $isp1”
================================================================
The above script detects:
1. Connection Type – Ethernet/Airport/Both (If Airport is active it detects the network name and its channel no.)
2. Local IP address of either or both the connection types
3. IP address of the router
4. DNS servers – if configured
5. External IP address
6. Name of the ISP – Tested to be working for two major broadband providers available locally

I would really like to know your views about the script.

Sorry for the long post, i am really excited using the Geektool and have been trying to optimize this code using different method to generate the results.

Thanks

Post new comment
The content of this field is kept private and will not be shown publicly.
3 + 0 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.