Tuesday, April 29, 2008

Bash Programming Samples

To declare script to use bash shell,
#!/bin/bash
To produce some interesting debugging output information,
#!/bin/bash -x
Set the passed arguments to an array, e.g. $ foo.sh bar
args = ("$@")   # args = bar
Use "$#" to get the number of arguments, e.g.
if [ "$#" -ne 1 ]; then
  echo "Must have exactly one argument."
  exit 1
fi
Find out if a file exists
if [ -f "foo.txt" ]; then
  cat foo.txt
fi

# Check if file does not exist
if [ ! -f "foo.txt" ]; then
  echo "foo.txt not found!"
fi
To get the return code from previous command, use $?
somecommand

if [ $? -eq 0 ]
then
  echo "command ran successfully."
else
  echo "somecommand failed." >&2
  exit 1
fi
somecommand

if [ $? -ne 0 ]; then
  # output to stderr
  echo "[`date`] [error]somecommand failed." >&2
  exit 1
fi
# output to stdout
echo "[`date`] [notice]somecommand succeeded."
To add timestamp to a command's output:
$ somecommand | sed "s/^/[`date`] /"

# Timestamp the error message, too
$ somecommand 2>&1 | sed "s/^/[`date`] /"
To check to see if an environment variable is set, use -z to check for zero-length string:
if [ -z "$TEST_VAR" ]
then
    export $TEST_VAR="some value"
fi
To unset an environment variable:
$ unset TEST_VAR

To print a newline with echo, use these option: (Note: Linux/Unix does not interpret carriage return char: \r)
       -n     do not output the trailing newline
       -e     enable interpretation of backslash escapes
e.g.
$ echo -e "Hello\nWorld "
Hello
World
$ echo -ne "Hello\nWorld "
Hello
World $
To get the script's base name and directory:
SCRIPTNAME=`basename $0`
SCRIPTDIR=`dirname $0`

Tuesday, April 1, 2008

Configuring color scheme for the 'ls' command

I have been having a hard time with the blue color in a Cygwin terminal (mintty) when I 'ssh' to other servers. It turns out I could fix this problem on a Linux server pretty easily by running this command:
$ dircolors -p > ~/.dircolors
I can also edit this file, '.dircolors', to customize my color scheme. Remember to re-login to see the changes.

As I research a little deeper, I found out how this file is being loaded. I see this code in "/etc/bashrc":
    for i in /etc/profile.d/*.sh; do
        if [ -r "$i" ]; then
            if [ "$PS1" ]; then
                . $i
            else
                . $i >/dev/null 2>&1
            fi
        fi
    done
And under "/etc/profile.d/", I see a file called, colorls.sh. In it I see the following code:
# color-ls initialization

alias ll='ls -l' 2>/dev/null
alias l.='ls -d .*' 2>/dev/null

COLORS=/etc/DIR_COLORS
[ -e "/etc/DIR_COLORS.$TERM" ] && COLORS="/etc/DIR_COLORS.$TERM"
[ -e "$HOME/.dircolors" ] && COLORS="$HOME/.dircolors"
[ -e "$HOME/.dir_colors" ] && COLORS="$HOME/.dir_colors"
[ -e "$HOME/.dircolors.$TERM" ] && COLORS="$HOME/.dircolors.$TERM"
[ -e "$HOME/.dir_colors.$TERM" ] && COLORS="$HOME/.dir_colors.$TERM"
[ -e "$COLORS" ] || return

eval `dircolors --sh "$COLORS" 2>/dev/null`
[ -z "$LS_COLORS" ] && return

if ! egrep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null ; then
        alias ll='ls -l --color=tty' 2>/dev/null
        alias l.='ls -d .* --color=tty' 2>/dev/null
        alias ls='ls --color=tty' 2>/dev/null
fi
So, the 'ls' color scheme file could be .dircolors, .dir_colors, or dircolors.xterm etc.