Thursday, May 5, 2011
Don't Abuse the Cat!
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
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 |
Friday, November 12, 2010
No KSH Love
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
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:
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.#!/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
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:
- Take an md5sum of the source MSI
- do a quick `split -d -b 12582912 MgtUI.msi MgtUI-chunk`
- Email myself the md5 and the first chunk in one email, then the other two chunks as separate emails
- Flip back to my laptop and fire up gmail
- Download the sent files
- Discover that Windows has saved the files with a permissions mask that Cygwin interprets as 0000.
- Use the security editor to set the file permissions on each file, individually to something that Cygwin will accept
- `cat` the chunks together
- Run an md5sum on the reconstituted MSI and verify it all came through ok
- 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.
