Take your bash_aliases with you

4 Jun

I love aliases. There are many useful shortcuts, e.g. „..“ as an alias for „cd ..“. If I got shell access to a system, I first install my version of vimrc, bashrc, bash_alias, and so on. I keep those files in a subversion repository, so I can synchronize them.

But what to do, when aliases are „system-sensitive“?

Some commands only work when required programs are installed or if a special directory exists. Most of the times, this is not a problem: if the program is not installed, the alias simply does not work. But what, if you want to install „colormake“ as „make“. Okay, this seems to be a bad idea, but I think, you understand the point .

A workaround would be to test weather a desired program is installed before installing an alias. This worked nicely. Until I got access to a Router and a very slow PC: the login needed 5 seconds. I decided to write a simple DSL, which creates my bash_alias based on a series of checks. The resulting file is than static. Here is the first part of the script:

#!/bin/sh
 
debug=0
#######
 
skip=1
supported=1
 
debug() {
    [ $debug -ne 0 ] && echo $* >&2
}
 
while read -r line; do
    debug -n "\"$line\" -> "
    if [ $skip -eq 0 ]; then
        if [ "${line#::#}" != "$line" ]; then
            debug "comment skipped"
        elif [ "${line#::}" != "$line" ]; then
            debug -n "control command: "
            case $line in
                ::c)
                    supported=1
                    debug "supported cleared"
                    ;;
                ::e:*)
                    cmd=${line#::e:}
                    if [ "$supported" -eq 0 ]; then
                        debug "section already skipped"
                    else
                        which $cmd >/dev/null 2>&1
                        if [ $? -eq 0 ]; then
                            debug "file exists" >&2
                        else
                            supported=0
                            debug "file does not exist. section skipped."
                        fi
                    fi
                    ;;
                ::p:*)
                    cmd=${line#::p:}
                    if [ $supported -eq 0 ]; then
                        debug "section already skipped"
                    else
                        perl -e "eval 'use $cmd'; exit (length \$@ == 0 ? 0 : 1);" >/dev/null 2>&1
                        if [ $? -eq 0 ]; then
                            debug "perl module exists"
                        else
                            supported=0
                            debug "perl module does not exist. section skipped."
                        fi
                    fi
                    ;;
                ::d:*)
                    cmd=${line#::d:}
                    if [ $supported -eq 0 ]; then
                        debug "section already skipped"
                    else
                        if [ -d "$cmd" ]; then
                            debug "directory exists"
                        else
                            supported=0
                            debug "directory does not exist. section skipped."
                        fi
                    fi
                    ;;
 
                ::r:*)
                    cmd=${line#::r:}
                    if [ $supported -eq 0 ]; then
                        debug "section already skipped"
                    else
                        if [ -r "$cmd" ]; then
                            debug "readable"
                        else
                            supported=0
                            debug "not readable. section skipped."
                        fi
                    fi
                    ;;
                ::n)
                    debug "inverting skip status"
                    if [ $supported -eq 0]; then
                        supported=1
                    else
                        supported=0
                    fi
                    ;;
                *)
                    echo "unsupported control command: $line" >&2
            esac
        else
            if [ $supported -eq 1 ]; then
                /bin/echo "$line"
                debug "supported"
            else
                debug "not supported"
            fi
        fi
    else
        if [ "$line" = "###END###" ]; then
            skip=0
            debug "skippping disabled"
        else
            debug "skipped"
        fi
    fi
done < $0
 
exit 0
###END###
#!/bin/bash
#WARNING - THIS FILE IS GENERATED AUTOMATICALLY

The file opens itself, seeks „###END###“ and processes everything after it. It defines several commands:

  • ::e:myfile – skip lines until next ::c if myfile does not exist
  • ::d:mydir – skip lines until next ::c if directory mydir does not exist
  • ::r:myfile – skip lines until next ::c if file myfile is not readable
  • ::n – inverts skipping state (imagine this as „else)
  • ::p:module – skip lines until next ::c if the perl module module is not installed
  • ::c – clear skip state

This is freaky to read, but simple to use and it can be easily extended. Note the explicit call of /bin/echo in line 97. This was the only way I found to get this script working witch both dash and bash (their „echo“ words differently if they find a backslash).

Okay, last but not least some examples for the second part (most parts are collected from several websites):

alias ..='cd ..'
alias ...='cd ../..'
alias 2..='cd ../..'
alias 3..='cd ../../..'
alias 4..='cd ../../../..'
alias 5..='cd ../../../../..'
 
alias path='echo -e ${PATH//:/\\n}'
 
alias ls='ls $LS_OPTIONS'
alias l='ls $LS_OPTIONS -l'
alias ll='ls $LS_OPTIONS -lA'
alias lg='ls | grep -i'
alias llg='ll |grep -i'
 
alias grep='grep --color=auto'
 
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
 
alias p='ps aux'
alias psg='ps aux | grep'
 
::e:tree
alias tree='tree -Csu'
::c
 
::e:screen
# starts screen in the background
alias bgscreen='screen -d -m'
::c
 
::e:ccze
alias c='ccze -m ansi'
::e:less
alias lless='c |less -NiR' # cat ... | lless
::c
 
::e:colordiff
alias diff=colordiff
::c
 
::p:Smart::Comments
alias cperl="perl -MSmart::Comments"
::c

To create a customized bash_aliases just run shomething like „sh mkalias.sh > ~/.bash_aliases„.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.