Showing posts with label unix. Show all posts
Showing posts with label unix. Show all posts

Thursday, May 5, 2011

Don't Abuse the Cat!

I'm a UNIX geek. The first UNIX-based system I interacted with was in 1989 in the second half of my freshman year at Penn State. I've had them as hobby systems for pretty much the entire time since college. I've also worked with them, in a professional capacity since the mid-90s. So, I've got a bit of experience with using them.

With that much time using UNIX systems, I've developed some habits and something bordering on beliefs about how to use them. When people do things that violate those habits or "beliefs", it kinda hits a nerve. One of the biggest (irrational) annoyances is when people fire up two commands to accomplish what could be done with one. The biggest annoyance in this family of annoyances is piping the output of cat to another program that can read the file directly. The most common of these seems to be the infamous `cat ${file} | grep ${PATTERN}`. The one that probably annoys me the most, however, is `cat ${file} | more`.

Whut. The. Fuck. Seriously? Did you just type that? Worse: did I actually see you write in an operations guide to use that as a standard procedure? FUUUUUUUUUUUUUUUUUUUUUUUCK

Seriously: I die a bit, inside, every time I witness someone write/say "cat file | grep TERM" (or similar). There's been more than a few SA's (team members, customers, etc.) that have heard me bellow, "don't abuse the cat!"

Friday, January 14, 2011

Annoying Defaults

I've said it many times before and I'm sure I'll say it many times in the future: every operating system sucks. If you haven't found what it is that makes your particular-favorite suck, you haven't been using it long enough, hard enough or both (either that, or you're just deluding yourself).

One of my co-workers is a Windows geek (well, it's what he's most comfortable using, any way). He likes to make cracks about Linux as though it will insult me, somehow. I'm not sure why he thinks this will work. I mean, it's not like I wrote Linux, so, I don't have any personal stake in it. But, whatever. Hell, I'll be the person at the head of the line to recite my own list of grievances about it. I'd be the first person at the head of the line bitching about pretty much any piece of technology I've used more than casually.

At any rate: Linux...

There are quite a number of things that I hate about Linux. In fact, when the previously-mentioned co-worker said to me, "Linux sucks," I agreed. I did, however, also say, "but it still sucks less than Windows."

One of the things I have always hated about Linux is its default shell. AT&T-derived UNIX operating systems use the old, bog-standard Bourne shell (/bin/sh) as their default shell. The BSDs brought us the C-Shell (/bin/csh) as the default shell (though, some derivatives later shifted to the TENEX C-Shell - /bin/tcsh). IBM and SGI decided that their OSes, being more up to date derivatives of the AT&T UNIX should have a more modern default shell. Both chose to have Korn Shell (/bin/ksh) as their default login shell.

I used to work for SGI. I've done a lot of work on IBM UNIX systems (AIX). So, I got used to having KSH as my default login shell. I also do a lot of scripting. KSH supports standard Bourne shell syntax but adds a number of useful extensions - in particular, I like the internal function construct. So, at this point in my UNIX-using career, I prefer KSH to all other shells.

Linux, unfortunately, being a "UNIX work-alike", has a different default shell than all other UNIX(y) operating systems. All of the previously-mentioned shells used to not be fully "in the public domain". So, when they needed an interactive shell, the Linux-coders came up with the Bourne Again Shell (or 'BASH'). It's kind of a hodgepodge of all of the shells that had existed when BASH was first created. It offers a lot of featuer-commonality with the other shells, plus some of its own tricks. Unfortunately, as with any "be all" solution, it's a giant ball of compromise rather than being particularly optimized.

Any way, none of that is exactly germane. The particular beef I have with Linux is the use of color in many applications and tools outputs. Where I particularly see it is in the output of the directory listing command, `ls`. In most of the Linux distributions I've used, the default login preferences specification turns on the use of color in the out put of `ls`. The output is what I refer to as "angry fruit salad." It's lots of garish shades of yellow, red, green and blue. It's rather hard to read.

Angry Fruit Salad
If I have rights to disable it, I immediately change the login profile to get rid of it. Unfortunately, it's usually the case that I don't have the rights to permanently disable it. So, the best I can do is, immediately upon login, is do `unalias ls`.

But... I shouldn't have to! Criminy: whose brilliant idea was it to make the BASH default alias for `ls`  display in color???

Friday, November 12, 2010

No KSH Love

I've been using UNIX operating systems (and workalikes) for a long time, now. The first UNIX system I touched was in 1989. As a longtime user of UNIX, I've developed some deeply set habits and preferences.

One such preference is my choice login-shell. I am a Korn Shell (KSH) user. Unfortunately, it's not super well-supported under Linux. It's made available more as a concession to dinosaurs, such as myself, than as a real "we think this is a good shell" type of effort. While each of the other myriad shells in Linux seem to come with a default shell initialization script in /etc/skel, KSH is given no such file.

All I can guess is that the distribution/package maintainers figure, "if this person's using KSH, they have enough clue to know how to put together a proper shell init file - no sense bothering to provide one." Worse, so few of today's UNIX "administrators" seem to get that there's shells other than BASH, that they don't bother to alter the contents of /etc/skel (or, if they do, they only do it for BASH and maybe CSH). Then again, there's a reason I put quotation marks around "administrators".


Tuesday, October 26, 2010

Why I Love Shell-Scripting

For those times when you have a text file of host to IP bindings, it's easy to see if you need to add shit to your DNS servers. You can write a script like:

for i in `cat hosts.txt`
do
   HOSTIP=`echo $i | cut -d : -f 1`
   FOUNDNAME=`echo $i | cut -d : -f 2`
   DNSNAME=`dig -x ${HOSTIP} | egrep -v "^;" | awk '/PTR/{print $5}'`
   if [ "${DNSNAME}" = "" ]
   then
      DNSNAME="#NOT_IN_DNS#"
   fi
   printf "%-15s%-40s%-40s\n" ${HOSTIP} ${DNSNAME} ${FOUNDNAME}
done

That gives you output that looks like:

192.168.90.24    labserv1024u.labzone.net.        labserv1024u.labzone.net
192.168.90.3     labserv1003u.labzone.net.        labserv1003u.labzone.net
192.168.90.20    labserv1020u.labzone.net.        labserv1020u.labzone.net
192.168.90.6     labserv1006u.labzone.net.        labserv1006u.labzone.net
192.168.80.20    #NOT_IN_DNS#                     labserv3014u
192.168.80.19    #NOT_IN_DNS#                     labserv1301u
192.168.90.130   labserv1130u-90.labzone.net.     labserv1130u.labzone.net
192.168.7.73     labserv1073u.labzone.net.        
192.168.90.26    labserv1026u-90.labzone.net.     labserv1026u.labzone.net
192.168.90.27    labserv1027u-90.labzone.net.     labserv1027u.labzone.net
192.168.90.21    labserv1021u.labzone.net.        labserv1021u.labzone.net
192.168.2.132    labserv3132u.labzone.net.        labserv3132u
192.168.7.188    labserv1188u.labzone.net.        labserv1188u
192.168.2.131    labserv3131u.labzone.net.        labserv3131u
192.168.2.240    labserv3071u.labzone.net.        labserv3071u
192.168.10.13    #NOT_IN_DNS#                     labmgr13
192.168.90.18    labserv1018u.labzone.net.        labserv1018u.labzone.net
192.168.90.7     labserv1007u.labzone.net.        labserv1007u.labzone.net
192.168.90.10    labserv1010u-90.labzone.net.     labserv1010u.labzone.net
192.168.36.73    #NOT_IN_DNS#                     labserv1073u
192.168.36.72    #NOT_IN_DNS#                     labserv1072u
192.168.7.73     labserv1073u.labzone.net.        labserv1073u
192.168.90.16    labserv1016u-90.labzone.net.     labserv1016u.labzone.net
192.168.90.25    labserv1025u.labzone.net.        labserv1025u.labzone.net
192.168.90.19    labserv1019u.labzone.net.        labserv1019u.labzone.net
192.168.90.2     labserv1002u.labzone.net.        labserv1002u.labzone.net
192.168.90.4     labserv1004u.labzone.net.        labserv1004u.labzone.net
192.168.36.71    #NOT_IN_DNS#                     labserv1071u
192.168.7.186    labserv1186u.labzone.net.        labserv1186u
192.168.90.9     labserv1009u.labzone.net.        labserv1009u.labzone.net
192.168.90.8     labserv1008u.labzone.net.        labserv1008u.labzone.net
192.168.90.17    labserv1017u.labzone.net.        labserv1017u.labzone.net
192.168.90.1     labserv1001u.labzone.net.        labserv1001u.labzone.net
192.168.90.5     labserv1005u.labzone.net.        labserv1005u.labzone.net

Then, you just grep for the "#NOT_IN_DNS#" lines and update your DNS servers to reflect your host table file.

Wednesday, August 25, 2010

The Kind of Hacks That Make You Feel Like You've Got a Furball

Ok, so, I had to dig through the script-fu memory banks to try to help a storage guy build a parameterized script to control the creation of metaluns on a CLARiiON array.
Now, the guy I'm working with is very much a "Windows guy". His way of doing things has been the "click-click-click-click-click" way. For better or worse, when you need to do tasks in a large-scale environment, all that clicking becomes very tedious. Being a Windows guy, his first impulse was to try scripting on Windows (*facepalm*). Needless to say, that proved an odious task. So, he asked if I could help him.
A lot of my scripting-fu relies on "finger memory". Basically, if I have an end state in mind, my hands just sort of vomit forth the code needed to reach that end state. Walking someone through that process can be rather painful, especially when you're as big into regex as I am and they have no clue. That, and having to simultaneously tutor on vi during the process just raises the aggro-stakes.
At any rate, the operation he needed to do required creating a script that used six variables to do the work. The first run through the script, we simply hard-coded the variables so we could vet the overall logic flow. Obviously, hard-coding a dynamic task is sub-optimal. So, we then went through the process or converting the hard-coded variables to ones that were set via passing parameters to the script at the command line.
Guy I'm working with is decently clued, so he didn't want a completely "blind" script (one with absolutely no validity checking). He wanted for the script to, at the very least, ensure that the user passed the requisite number of arguments. Should the script user fail to do so, they'ed get a usage statement. So, what was the most effective way to determine whether the number of arguments passed matched the number of arguments that the script needed in order to do it's job?
After mulling it over, I came up with the following bit of ugliness:
#!/bin/ksh

NUMVARS=0
for i in "$@"
do
   echo "Args for $0 is $i"
   NUMVARS=$(($NUMVARS + 1))
done

echo $NUMVARS

if [ ${NUMVARS} -lt 6 ]
then
   echo "Insufficient arguments"
fi
It's not exactly "ideal", but it's a start. How suitable it will end up being in the context of the final script is yet to be seen.
If you've got ideas on a more elegant approach within a /bin/sh-type construct, I'd love to hear it. Probably going to have to shred that, any way, when we add in the other bounds-checking.

Thursday, August 19, 2010

Stop Thinking Like a UNIX-tard

Ok, so, I wanted to transfer an installation package from my system at work to my system at home, but didn't want to ass around with setting up trusted SSH keys. So, what do I do? I try to email the file.

Now, mind you, this was s 36MB MSI file. I knew that GMail had less restrictions on file sizes, so, I figured, "mail it to myself". Gmail apparently sets a 25MB filesize limit. "Hmm... What to do," says I.

AH! I've got Cygwin installed both on the system the MSI's sitting on and my laptop. I'll just split the file up into manageable chunks and email myself the chunks:

  1. Take an md5sum of the source MSI
  2. do a quick `split -d -b 12582912 MgtUI.msi MgtUI-chunk`
  3. Email myself the md5 and the first chunk in one email, then the other two chunks as separate emails
  4. Flip back to my laptop and fire up gmail
  5. Download the sent files
  6. Discover that Windows has saved the files with a permissions mask that Cygwin interprets as 0000.
  7. Use the security editor to set the file permissions on each file, individually to something that Cygwin will accept
  8. `cat` the chunks together
  9. Run an md5sum on the reconstituted MSI and verify it all came through ok
  10. Run the installer

I'm thinking I could probably have gen'ed a DSA-2048 key and set it up as an authorized key, SCPed the file across and installed it in well less than the time it took to do the prior ten steps. Oh well... There's about a bajillion ways to skin a cat. My UNIX-tard brain made me do it one of the more painful ways.