Como estender aliases de bash

10

Como criar um alias que realmente estenda outro alias de mesmo nome Bash?

Por que:

Eu costumava ter GREP_OPTIONS definido em .bashrc para algo assim:

GREP_OPTIONS="-I --exclude=\*~"

Eu também tinha um script (digamos, setup-java.sh ) que eu chamaria antes trabalhando em alguns projetos Java. Ele conteria a linha:

GREP_OPTIONS="$GREP_OPTIONS --exclude-dir=classes"

Se eu também usar o Sass, chamo setup-sass.sh , que contém a linha:

GREP_OPTIONS="$GREP_OPTIONS --exclude-dir=\*/.sass-cache"

Mas GREP_OPTIONS foi depreciado e aparentemente, a solução padrão é criar um alias ou algum script ...

    
por brandizzi 10.01.2016 / 02:13

3 respostas

12

O Bash armazena os valores dos aliases em um array chamado BASH_ALIASES :

$ alias foo=bar
$ echo ${BASH_ALIASES[foo]}
bar

Com o parâmetro expansão podemos obter o último alias de conjunto (se existir) ou o valor padrão:

alias grep="${BASH_ALIASES[grep]:-grep} -I --exclude=\*~"

Agora, basta fazer isso em setup-java.sh :

alias grep="${BASH_ALIASES[grep]:-grep} -I --exclude=\*~  --exclude-dir=classes"

... e finalmente em setup-sass.sh :

alias grep="${BASH_ALIASES[grep]:-grep} -I --exclude=\*~ --exclude-dir=\*/.sass-cache"

Se as três linhas forem chamadas, obteremos o que queremos:

$ echo ${BASH_ALIASES[grep]:-grep}
grep -I --exclude=\*~ -I --exclude=\*~ --exclude-dir=classes -I --exclude=\*~ --exclude-dir=\*/.sass-cache
    
por 10.01.2016 / 02:13
12

aliases chain se você terminá-los com espaços.

alias print='printf %s\n ' hey='"hello, fine fellow" '
print hey
hello, fine fellow

Você pode escrever scripts inteiros assim, se você for louco o suficiente. De qualquer forma, se você quiser estender um alias, apenas certifique-se de que o alias que você deseja estender termine em um espaço e corrija outro.

alias grep='printf "%s " -I --exclude=\*~ '    \
      exdir=' --exclude-dir=classes '          \
      exsass='--exclude-dir=\*/.sass-cache '
grep exdir exsass exdir exsass
-I --exclude=*~ --exclude-dir=classes --exclude-dir=*/.sass-cache --exclude-dir=classes --exclude-dir=*/.sass-cache
    
por 10.01.2016 / 03:32
1

Uma função é uma opção melhor que um alias extensível aqui.

grep_options=( )
grep() {
  exec /usr/bin/grep "${grep_options[@]}" ${GREP_OPTIONS} "$@"
}

Dessa forma, você tem duas opções para adicionar opções ao ambiente:

  • Altere a matriz grep_options ; isso corretamente suporta opções com espaços, caracteres de glob globais e outros casos de canto:

    grep_options+=( --exclude-dir=classes --exclude-dir='*/.sass-cache' )
    
  • Use a tradicional variável escalar GREP_OPTIONS , apesar de suas armadilhas (veja BashFAQ # 50 para entender algumas delas) :

    GREP_OPTIONS+=' --exclude-dir=classes '
    

Dito isso, se você quiser que suas opções sejam refletidas por grep instâncias chamadas fora do shell, nem um alias nem uma função funcionarão. Em vez disso, você desejará um script de wrapper colocado anteriormente em seu PATH do que o comando real grep . Por exemplo:

# in ~/.bash_profile
[[ -e ~/bin ]] && PATH=$HOME/bin:$PATH

... e, em ~/bin/grep :

#!/bin/bash

# load overrides to grep_options on GREP_OPTIONS from local dotfiles
source ~/.bash_profile
source ~/.bashrc

# ...and use them:
exec /usr/bin/grep "${grep_options[@]}" ${GREP_OPTIONS} "$@"
    
por 10.01.2016 / 18:41

Tags