Search this blog ...

Tuesday, April 19, 2011

dircolors – color ls unix directory listings – danger of overriding shell built-ins

I ran in to a crazy issue today that stemmed from a built-in function override configuration setting that I have leveraged for the best part of a decade. I’m amazed that this is the first time I actually noticed it!

I have a environment setup script for one of my installations like the following ...

export MW_HOME=/u01/app/oracle/product/Middleware
export JAVA_HOME="`ls -d ${MW_HOME}/jdk16*`"
export PATH=$JAVA_HOME/bin:$PATH

The JDK path is not hardcoded as this is a pre-release environment, and the JDK is often patched and the directory name changes as a result.

A script I was invoking had a simple test like the following:

if [ x${PATH} != x ]; then

When I ran the shell script from plain vt100 terminal, everything worked perfectly.  When I fired the script up from an xterm running inside VNC, I hit an error like the following:

./ line 2: [: too many arguments

The reason for the error, the string JAVA_HOME ended up containing ANSI characters when run from xterm.

For example, from an XTERM

echo `ls -d /tmp` > file.txt

file.txt contained ... ^[[00m^[[00;34m/tmp^[[00m ^[[m

, whereas from the VT100 terminal:

echo `ls -d /tmp` > file.txt

file.txt contained ... /tmp

It turns out, I had a zsh function setup-for/overriding the ls command so as to use color listings when invoked from an xterm by passing the --color option.  The function was as follows:

ls ()
  [[ $TERM = (*xterm*|ansi|linux|dtterm) ]] && set -- --color "$@"
  command ls -v "$@"

The fix was to change the --color option to be --color=auto so that the ANSI escape sequences were only output if the standard output is a terminal (but not for things like scripts etc).

ls ()
  [[ $TERM = (*xterm*|ansi|linux|dtterm) ]] && set -- --color=auto "$@"
  command ls -v "$@"

Moral of the story, be extremely careful using shell functions to override standard built-in commands, and make sure you understand the impact of switches!


So my good mate and colleague Dragos states:

You should not rely on 'ls' (or any other command), as it can be an alias or function to anything else.

The fix is in your environment script to use /bin/ls or =ls, yes "equal sign ls"

There's a way to force filename expansion too:


Thursday, April 7, 2011

Online Open Port Check Tool

The RCCB / Residual Current Device in my place has a nasty habit of tripping whenever the house is vacant for more than a couple of days. For the remaining 99% of the time that I’m home, it never trips.  I haven’t been able to isolate exactly what triggers it, but upon my return I’m faced with a fridge/freezer full of ruined food.

Anyway, given the electricity is completely lost when this RCCB triggers, I really need a simple tool that polls my router (like a ping) to see if it responds, and if not, gives me some type of warning.

I run OpenVPN on the router over TCP port 443, and it appears the various online port scanning tools are able to detect the presence of the port being open.

The following is a list of sites that I’ve found that allow one to scan a specific remote host and port (that differs to the host/proxy of the incoming client):

My favourite is the latter, as it allows you to potentially bookmark the location; for example, to check if google port 80 open:

If anyone knows a site out there that offers remote port polling with SMS/email notification in the event the service is down, let me know!

I may have to build something otherwise on Google App Engine using the URL fetch capabilities

Here is the API