Previamente… Funções úteis em bash

Esta nova versão é ligeiramente mais eficiente, porque não existem mais comandos echo e pipes envolvidos no processamento. Apenas um eval e um script awk.


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)
}

Estas funções também foram melhoradas removendo usos desnecessários de sub-shells para 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}
}

Se, como eu, sempre tenta organizar e ter uma configuração modular, mais cedo ou mais tarde vai separar a configuração bash em vários ficheiros. Além disso, se quiser usar a mesma em várias máquinas, esta função dá jeito:


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

Desta forma pode tentar incluir os fragmentos apenas onde e quando existem:


1
source_if_exists ${HOME}/etc/bash_completion

Algo que também é comum fazer é acrescentar um directório a uma variável de ambiente. Quando se faz uma configuração para várias máquina é sempre um inconveniente assegurar que os directórios existem. Estas funções tratam do problema:


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})
}

Exemplos:


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

É frequente que as variáveis de ambiente com directórios apresentem entradas duplicadas o que torna a pesquisa menos eficiente. Esta função assegura que cada directório ocorre apenas uma vez e retém apenas a primeira entrada, mantendo por isso a ordem.


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";           \
         }'
)
}

Examples:


1
2
unique_path PATH
unique_path MANPATH
%d bloggers like this: