More Tools For Building Tools

I’m working on more bash completions. This time for some of the command line tools Apple provides for sysadmins.

I decided there had to be a way to get a list of the options from the man page for a tool. After all they are all in there.

So I built a command line piece by piece. As an example let’s get a list of the options (with some caveats) for the tool pkgbuild. We start with man pkgbuild | col -b , the col -b step takes out the special characters man uses to show bold on screen. Now find all lines containing -- with grep, I liked grep -e '--'. If you have a look at the output of that we are getting close.

Next I decided to use sed to do a find and replace for the option itself. After some playing around I ended up with sed -e 's#.*\(--[a-zA-Z-]*\).*$#\1#' An important note for young players, it did take some time and a few tries to get that substitution just right. Don’t be afraid and remember Google (and Stack Exchange) are your friends.

First, I should point out an old Unix hand’s trick. Most of the time you see sed substitution commands using / as the separator but sed can use anything but \ or newline – it uses the first character it sees after the ‘s’. I usually use # as it makes the \ used for special characters easier to spot and the string easier to read.

So now we have a look at the find portion of the sed command. The .* matches a string of zero or more characters, then the \( is the start of what we want to match. The option starts with -- and is followed by a string of alpha characters of either case or a -. Then we end the match with \) and finish with zero or more characters till the $,
which is the end of the line. Then all of the line is replaced with what we matched in the find half by the \1. Whhheeewwww.

Now we have a list but it can contain the same option multiple times so we pass it through sort and uniq. Our final command line is :

man pkgbuild | col -b | grep -e '–-' \
 | sed -e 's#.*\(–-[a-zA-Z-]\).*$#\1#' \
 | sort | uniq

You may find that you end up with the odd extra line so you should give it a check. If the options only have a single - in front of them then I found that grep -e ' -' | sed -e 's/.*\(\s-[az]*\)/\1/' | seems to work quite well, though some man pages want a \t instead of a space in that grep command.

You will notice that this leaves the - or -- in place. I like that as a check of my command line work and it’s easily removed in our editor.

If you are a BBEdit user then you can add | bbedit at the end for the output to open straight into a new BBEdit window. Sweet. Oh, did you know that the bbedit command line tool has a —-resume flag? Put this in your EDITOR shell variable and when you close the window after editing your git commit message it will take you back to your shell window. So I have export EDITOR='bbedit -w —resume in my .bash_profile.

Of course, in the time it took me to develop the command line and write this blog post
I could have written several bash completion scripts, but where’s the fun in that?


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s