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„.