Como testar possíveis conflitos ao usar o alias no bashrc?

12

Existe uma maneira simples de listar todos os conflitos de comando que ocorreram no sistema devido à atualização do bashrc envolvendo comandos de alias?

Por exemplo, alguém escreve alias ls=/path/to/user-generated/executableno bashrc. Como alguém descobre que isso está mascarando um comando real ( ls). Uma maneira parece ser executar todos os aliases antes e depois do sourcing do bashrc e diferenciar a saída. Existem maneiras melhores?

Estou executando o Ubuntu 12.04.

bash --versão

Lançamento do GNU bash, versão 4.2.24 (1) (i686-pc-linux-gnu)

user13107
fonte
Como observação lateral, normalmente é mais útil para as pessoas que responderem se você fornecer sua versão do bash, em vez da versão do SO, ao fazer uma pergunta específica ao bash.
Jordanm 18/10
@jordanm Atualizado.
user13107

Respostas:

8

Para descobrir quais comandos são mascarados por aliases, faça algo assim:

alias | sed 's/^[^ ]* *\|=.*$//g' | while read a; do
  printf "%20.20s : %s\n" $a "$(type -ta $a | tr '\n' ' ')"
done | awk -F: '$2 ~ /file/'

Explicação

aliassozinho lista aliases definidos e sedextrai seu nome. O loop while é executado type -taem cada um deles e awkimprime as linhas que contêm alias e arquivo.

Thor
fonte
15

Você pode usar typepara descobrir como um comando seria interpretado pelo bash.

choroba
fonte
Por exemplo, type lsimprime ls is aliased to `ls --color=auto'aqui.
l0b0
O mesmo funciona which, mas não o faço agora se ambos (tipo, qual) os componentes internos do shell são os mesmos.
matemática
@ Mat: type whichdiz-lhe which is /usr/bin/which, por isso não é um builtin. Portanto, ele não pode dizer se algo está embutido ou não (por exemplo, which echoversus type echo).
choroba
Acho que depende do shell que você usa: type which which is a shell builtinestou usando o zsh.
matemática
@ math: A pergunta original está marcada / bash.
Choror 18/12/12
7

Como sua primeira pergunta, não há como listar os conflitos, já que o bash usa uma tabela de hash internamente, ela registra apenas a última substituição.

Para descobrir se um comando é um alias, use alias lsno seu caso, se ele disser algo como "não encontrado", então não é um alias, caso contrário, é.

Para iniciar a função original desconsiderando o alias, prefixe uma barra, por exemplo \ls, iniciará o hash real ls, ignore o alias.

EDITAR

Se você quiser saber rapidamente se um comando é um alias, poderá ativar o modo de depuração set -xagora, se executar ls:

insira a descrição da imagem aqui

Você verá uma saída de depuração do comando real sendo executada

Para desabilitar o modo de depuração, use set -

margarida
fonte
Obrigado. Mas não entendi o aliaspapel. E se um usuário não souber que existe um comando (por exemplo ls)? A única coisa que ele parece saber depois de executar alias lsé para o que é mapeado e não para o que foi originalmente mapeado. Eu acho que um terá que executar todos os comandos com e sem \ para encontrar conflitos.
user13107
@ user13107 atualizou a resposta
daisy
Obrigado. Como desarmar o rastreamento?
user13107
@ user13107 atualizado novamente ;-P
daisy
1
"não há como listar os conflitos" - você simplesmente não é imaginativo o suficiente.
Camh
6

Você pode usar o bash embutido compgen para obter uma lista de todos os comandos e todos os aliases usando compgen -ac. Qualquer comando que também seja um alias será duplicado nesta lista, portanto a solução simples e ingênua é procurar duplicatas na saída de compgen -ac.

No entanto, duplicatas também podem aparecer se um comando estiver no caminho duas vezes. Por exemplo, eu tenho /bin/whiche /usr/bin/whichentãocompgen -ac , listarei whichduas vezes, mesmo que não seja um alias.

Portanto, o que é necessário é obter todas as duplicatas compgen -ace comparar com uma lista de aliases. Apenas duplicatas que também são aliases são aqueles que ocultam comandos. Podemos fazer isso com o comm(1)comando e com a substituição do processo bash.

comm -12 <(compgen -a | sort) <(compgen -ac | sort | uniq -d) 

compgen -a | sorté a lista de todos os aliases (classificados para comm). compgen -ac | sort | uniq -dé a lista de todas as duplicatas da lista de comandos e aliases. comm -12produz apenas as linhas comuns a ambos.

camh
fonte
5

Você pode usar o recurso de depuração do shell para ver exatamente o que está acontecendo quando o bash chama um shell interativo. A seguir, mostramos todos os aliases atribuídos quando um shell interativo é gerado a partir de um shell de logon:

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> ativar a depuração
  • -l -> shell de login
  • -i -> shell interativo
  • -c -> comando

A execução da saída do comando é necessária para que o shell retorne. o-i é necessária neste caso porque o bash não iria criar um ambiente interativo para executar um comando contrário.

Aqui está um exemplo do meu sistema:

$ bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
++ alias 'ls=ls --color=auto'
$ alias -p
alias ls='ls --color=auto'

Para ver qual arquivo foi originado pela última vez quando o alias foi atribuído para determinar o arquivo em que ocorreu, você pode estender o grep:

bash -x -l -i -c 'exit' 2>&1 | grep -E ' (alias|[.]|source) '

Isso pode retornar falsos positivos, mas deve ser bom se você estiver inspecionando manualmente os dados retornados. O número de símbolos '+' na frente do comando executado indica a profundidade.

+ . /home/jordan/.bashrc
++ alias 'ls=ls --color=auto'
++ . /home/jordan/.foo
+++ alias t=test
++ alias t=test2

Nesta saída de amostra, mostra que .bashrc define um alias para ls, .foo aliases te, em seguida, .bashrc substitui o alias anterior de t.

jordanm
fonte
Obrigado. Isso é certamente útil, mas não é possível ver como o conflito cria aliases.
user13107
@ user13107 Adicionei mais alguns detalhes que devem ser úteis. Definir um alias para um novo valor não é um alias "conflitante". É um comportamento documentado normal, e é por isso que é necessário um caminho alternativo.
Jordanm 18/10