Previously… Useful bash functions

This new version is a tad more efficient since there are no more echo and pipes involved on the processing. Just one eval and one awk script.


1
2
3
4
5
6
7
8
9
10
11
12
unique_path() {
  eval $(awk -v VAR="${1}" 'BEGIN {                 \
    if((N=split(ENVIRON[VAR],vals,":"))<2) exit(0); \
    sep = out="" ; i=split(out,seen);               \
    do { if(!(vals[++i] in seen)) { seen[vals[i]];  \
           gsub("["]","\\"",vals[i]);             \
           out=sprintf("%s%s%s",out,sep,vals[i]);   \
           sep=":";                                 \
    } } while (i<N);                                \
    printf "%s="%s"; export %s;\n",VAR,out,VAR;   \
  }'
/dev/null)
}

Similarly, these also had remove unnecessary uses of sub-shell echo…


1
2
3
4
5
6
7
8
9
10
11
safe_prepend_path() {
  VAR=$1 ; shift ; eval VAL=\$${VAR}
  for i_;do [ -d "$i_" ] && VAL=$i_${VAL:+":$VAL"} ;done
  eval export ${VAR}=${VAL}
}

safe_append_path() {
  VAR=$1 ; shift ; eval VAL=\$${VAR}
  for i_;do [ -d "$i_" ] && VAL=${VAL:+"$VAL:"}$i_ ;done
  eval export ${VAR}=${VAL}
}


If you are like me, you have regular conference calls where you have to send some bridge identification number or profile to sign in.

On a Nokia N9 it’s really not obvious how to set up a contact that automatically sends those digits after the call is connected, especially if you use the Swype virtual keyboard.

The first thing to know is that in order to specify a pause separation for the digits you need to enter a ‘p’. To me this was a surprise, as I was used to other cellphones which used the comma (‘,’), semi-colon (‘;’) or period (‘.’) for the same purpose, sometimes with different pause intervals

If you have swype, when you enter a phone number here is what the screen looks like the image below, a numeric pad virtual keyboard. You disregard the currency symbols and try to enter either the comma or the period and they don’t work.

What you need to do is to tap the bottom ABC button so that it switches to the main alphanumeric virtual keyboard and then you can enter the ‘p’.


You have the stock virtual keyboard things are a little simpler, you tap the ‘‘ and notice how it becomes red underlined, tap again and it becomes a ‘+’ and again… the ‘p’ finally. The three taps have to be in quick succession.



If you, like me, strive to keep a well organized and modular configuration setup, sooner or later will split your bash configuration into multiple files. And if you want it to be valid for multiple machines you’ll appreciate the following function:


1
2
3
source_if_exists () {
    for i_; do test -f "$i_" && source "$i_"; done
}

This way, you can try to process other configuration fragments only when they exist:


1
source_if_exists ${HOME}/etc/bash_completion

Another common need for bash configuration is to either append or prepend paths to an environment variable. When doing a configuration for multiple machines it is always a pain to make sure those paths exist. These functions take care of that making adding directories to the path a breeze:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
safe_prepend_path() {
    VAR=$1
    shift
    VAL=$(eval echo \$${VAR})
    for i_; do
        test -d "$i_" && VAL=$i_${VAL:+":$VAL"}
    done
    eval export ${VAR}=$(echo ${VAL})
}

safe_append_path() {
    VAR=$1
    shift
    VAL=$(eval echo \$${VAR})
    for i_; do
        test -d "$i_" && VAL=${VAL:+"$VAL:"}$i_
    done
    eval export ${VAR}=$(echo ${VAL})
}

Example:


1
2
safe_prepend_path PATH /opt/local/bin ${HOME}/bin
safe_append_path MANPATH /opt/local/man ${HOME}/man

Also, it is not unusual to have some path variables with duplicate entries, which is not very efficient. This function makes sure that a path only occurs once, and retains only the first occurrence, thus keeping the search order intact.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
unique_path() {
    eval export $1=$(echo $(eval echo \$${1}) | \
        awk -F:                   \
        '{ a[$1];                 \
           printf "%s",$1;        \
           for(i=2;i<=NF;i++) {   \
             if(!($i in a)) {     \
               printf ":%s",$i;   \
             };                   \
             a[$i];               \
           };                     \
           printf "\n";           \
         }'
)
}

Example:


1
2
unique_path PATH
unique_path MANPATH
keep looking »