25 February 2009

Waiting for box to come back

This is a quick and easy tip, for the detail-oriented! Say a computer that you're interested in is down for some reason. Maybe you've rebooted it and you want to know the second that it's back on-line. Or maybe it's someone else's box and it's down and you (again) want to know as soon as it's up. You could just run ping and watch for the responses, but that's more traffic than is needed for a box that you know is down. And, what if you know it's going to be a while?

'ping' has a lot of great options and we can use those to send fewer packets and then quit as soon as the box responds. (So, if you're getting coffee or something when it comes back on-line, you're not just pinging it all day.) Here's the solution:

$ /sbin/ping -i 4 -o ; echo -e '\a'
PING ( 56 data bytes

--- ping statistics ---
35 packets transmitted, 1 packets received, 97.1% packet loss
round-trip min/avg/max/stddev = 2.856/2.856/2.856/0.000 ms

The '-i' option sets the wait between packets in seconds, which would have been 1 second by default. This was for an important box that I rebooted and needed to check as soon as it came back up. If the box was going to be down for a longer and/or unknown amount of time, you could set that higher, like 30 seconds. The '-o' option is what causes ping to exit as soon as it gets one good response. Then, I added the console beep ("echo -e '\a'") after the ping so I could go about something else and still be notified. (That form works for bash and sh, at the least.)

Hey, and I saved over 100 unnecessary packets! :) I did say this was for the "detail-oriented."

Seriously, though, I don't like the default behavior of ping -- going on forever until you stop it. I use it often and get tired of pressing '<Ctrl>-c' all the time. That's why I alias 'ping' to 'ping -nc 5'. (And, also why I used the full path above, to escape my own alias.) I think people mostly use ping for two different things: to measure the network delay to another host and to check reachability or presence a host. My alias does a reasonable job for both of those cases. The present case is what I'd consider to be a special and less common usage: waiting for a host you know is normally reachable to come back on-line.

07 February 2009

bash history grep alias

In a previous post, I introduced many useful bash shell aliases that I use. There's one that I've made a notable improvement to that I'd like to share. If you spend a lot of time on the command-line and use bash, you should really try this out.

'bhg', for "bash history grep," was a pretty simple alias to search through your bash history file. Previously, I used it like this:
alias bhg='cat $HISTFILE | grep'

The deficiency I found with it is that I often keep a shell open for days (even weeks!) at a time. So, I may be searching for a command that has not been written to the history file. What I'd like, then, is one 'bhg' alias that will find any command from my current shell history or my history file. The bash 'history' built-in will give you all of the current shell's command history. We just need to strip out the line numbers -- easy enough with 'sed' -- and then con-'cat'-enate that with the history file and we're in business. So, this is what I use now to accomplish all that:
alias bhg="history | sed 's/^ *[0-9]* *//' | cat $HISTFILE - | grep "

As I mentioned before, if you find this useful, you can make it even more useful by increasing the history size variables in your ".bash_profile". Namely, 'HISTSIZE', which controls how many lines of current history will be available via the history command, and 'HISTFILESIZE', which controls how many lines of command history will be written to your history file. They both default to 500, I think, which I've found to be way too small for my purposes.