adiando argumento em “alias” em .bashrc

1

Eu sou um usuário burro, que trabalha com o LINUX (Ubuntu 14) Meu laptop recém-adquirido me obriga a usar o shell bash e tem .bashrc . Eu costumava usar o C-shell antes disso e tentei copiar seus aliases de .cshrc a .bashrc com algumas edições óbvias.

Uma coisa não funciona - o argumento diferido. Como exemplo - meu comando .cshrc :

alias rm 'mv -f \!* $HOME/zap'

quando escrito em .bshrc como

alias rm = 'mv -f \!* $HOME/zap'

gera uma mensagem de erro:

bash:alias: rm: not found
bash:alias: mv -f \!* $HOME/zap: not found

(o diretório zap foi criado por mim antecipadamente)

O que devo usar em vez de \!* ?

    
por Al Kap 28.07.2016 / 18:10

2 respostas

1

Você deve usar funções do shell em vez de aliases nesses casos. É um pouco mais para digitar, mas permite que você seja mais flexível:

function rm {
  if ! test -d "$HOME/zap"; then
    echo "No zap in home" >&2
    return 1
  else
    mv -f -- "$@" "$HOME/zap/"
  fi
}

O $@ expandirá para os argumentos que você fornecer rm na linha de comando. O -- é necessário para sinalizar o fim dos sinalizadores de linha de comando (para que rm -f , onde -f é um arquivo, seja possível, rm e mv não compartilham muitas sinalizações de linha de comando).

Para acessar o comando rm original, use \rm ou command rm .

O teste da existência de $HOME/zap , a saída de uma mensagem de erro para o erro padrão e a saída com status de saída diferente de zero na função é apenas para mostrar que você pode fazer o que quiser. Você poderia, obviamente, reduzi-lo a apenas

function rm {
  mv -f -- "$@" "$HOME/zap/"
}

O manual bash contém a declaração:

For almost every purpose, aliases are superseded by shell functions.

Os aliases são realmente úteis apenas para etiquetando suas bandeiras favoritas em ls e coisas assim.

    
por 28.07.2016 / 18:30
1

Se você remover espaços desnecessários, o comando terá alguma esperança de trabalhar:

$ alias rm='mv -f \!* $HOME/zap'

Vamos apenas adicionar um eco para "ver" o que acontece sem mover arquivos:

$ alias rm='echo mv -f \!* $HOME/zap'
$ rm one two three
mv -f !* /home/immf/zap one two three

O que simplesmente mostra que o histórico do bash não funciona da mesma maneira que os comandos do histórico do csh porque o uso do csh:

If the alias contains a history reference, it undergoes History substitution as though the original command were the previous input line.

e o bash não. Ainda mais, aliases bash têm esse limite:

There is no mechanism for using arguments in the replacement text. If arguments are needed, a shell function should be used.

Aliases are not expanded when the shell is not interactive.

Ou seja: não há como reutilizar argumentos na linha atual e, mais ainda, os aliases não funcionam em scripts (por padrão).

No entanto, a intenção do alias é reutilizar os mesmos argumentos e adicionar um último diretório como o destino para onde mover os arquivos:

$ alias rm 'echo mv -f \!* $HOME/zap'        ### in csh
$ rm one two 333                             ### in csh
mv -f one two 333 /home/user/zap

O que poderia ser feito facilmente com a opção -t de mv (não disponível em mv do bsd):

$ alias rm='echo mv -f -t "$HOME/zap"'
$ rm one two 333
mv -f -t /home/user/zap one two 333

Resumindo: seria sensato usar uma função.

    
por 29.07.2016 / 06:54