Comment tester les conflits possibles en utilisant l'alias dans bashrc?


12

Existe-t-il un moyen simple de répertorier tous les conflits de commandes qui se sont produits dans le système en raison de la mise à jour bashrc impliquant des commandes d'alias?

Par exemple, quelqu'un écrit alias ls=/path/to/user-generated/executableen bashrc. Comment découvre-t-on que cela masque une commande réelle ( ls). Une façon semble être d'exécuter tous les alias avant et après le sourcing bashrc et de différencier la sortie. Y a-t-il de meilleures façons?

J'utilise Ubuntu 12.04.

bash --version

GNU bash, version 4.2.24 (1) -release (i686-pc-linux-gnu)


En remarque, il est généralement plus utile aux personnes qui répondent si vous fournissez votre version de bash, plutôt que la version du système d'exploitation lorsque vous posez une question spécifique à bash.
jordanm

@jordanm Mis à jour.
user13107

Réponses:


8

Pour savoir quelles commandes sont masquées par les alias, procédez comme suit:

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

Explication

aliasseul répertorie les alias définis et sedextrait leur nom. La boucle while s'exécute type -tasur chacun d'eux et awkimprime les lignes qui contiennent à la fois l'alias et le fichier.


15

Vous pouvez utiliser typepour découvrir comment une commande serait interprétée par bash.


Par exemple, type lsimprime ls is aliased to `ls --color=auto'ici.
l0b0

La même chose fonctionne avec which, mais je ne le fais pas maintenant si les deux (type, qui) commandes internes du shell sont les mêmes.
math

@math: type whichvous le dit which is /usr/bin/which, ce n'est donc pas une fonction intégrée. Par conséquent, il ne peut pas vous dire si quelque chose est intégré ou non (par exemple which echoversus type echo).
choroba

Je suppose que cela dépend du shell que vous utilisez: type which which is a shell builtinj'utilise le zsh.
math

@math: La question d'origine est taguée / bash.
choroba

7

Comme première question, il n'y a aucun moyen de lister les conflits, puisque bash utilise une table de hachage en interne, il n'enregistre que le dernier remplacement.

Pour savoir si une commande est un alias, utilisez alias lsdans votre cas, si elle vous dit quelque chose comme "non trouvé" alors ce n'est pas un alias, sinon c'est le cas.

Pour lancer la fonction originale sans tenir compte de l'alias, préfixez une barre oblique, par exemple \lslancera le vrai ls haché, ignorez l'alias.

ÉDITER

Si vous voulez savoir rapidement si une commande est un alias, vous pouvez activer le mode de débogage par set -x, maintenant si vous exécutez ls:

entrez la description de l'image ici

Vous verrez une sortie de débogage de la vraie commande en cours d'exécution

Pour désactiver le mode de débogage, utilisez set -


Merci. Mais je n'ai pas eu le aliasrôle. Que faire si un utilisateur ne sait pas qu'il existe une commande (par exemple ls)? La seule chose qu'il semble savoir après avoir couru, alias lsc'est à quoi il est mappé et non à quoi il a été mappé à l'origine. Je suppose que l'on devra exécuter toutes les commandes avec et sans \ pour trouver des conflits.
user13107

@ user13107 a mis à jour la réponse
daisy

Merci. Comment désactiver le suivi?
user13107

@ user13107 mis à jour à nouveau ;-P
daisy

1
"il n'y a aucun moyen d'énumérer les conflits" - vous n'êtes tout simplement pas assez imaginatif.
camh

6

Vous pouvez utiliser la commande bash intégrée compgenpour obtenir une liste de toutes les commandes et de tous les alias utilisant compgen -ac. Toute commande qui est également un alias sera dupliquée dans cette liste, donc la solution naïve simple consiste à rechercher des doublons dans la sortie de compgen -ac.

Cependant, des doublons peuvent également apparaître si une commande se trouve sur le chemin deux fois. Par exemple, je l'ai /bin/whichet je vais /usr/bin/whichdonc compgen -acénumérer whichdeux fois, même s'il ne s'agit pas d'un alias.

Il faut donc obtenir tous les doublons compgen -acet les comparer à une liste d'alias. Seuls les doublons qui sont également des alias sont ceux qui masquent les commandes. Nous pouvons le faire avec la comm(1)commande et avec la substitution de processus bash.

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

compgen -a | sortest la liste de tous les alias (triés pour comm). compgen -ac | sort | uniq -dest la liste de tous les doublons de la liste des commandes et des alias. comm -12ne produit que les lignes communes aux deux.


5

Vous pouvez utiliser la fonction de débogage du shell pour voir exactement ce qui se passe lorsque bash appelle un shell interactif. Les éléments suivants devraient vous montrer tous les alias attribués lorsqu'un shell interactif est généré à partir d'un shell de connexion:

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> activer le débogage
  • -l -> shell de connexion
  • -i -> shell interactif
  • -c -> commande

L'exécution de la commande exit est nécessaire pour que le shell revienne. Le -iest requis dans ce cas car bash ne configurerait pas un environnement interactif pour exécuter une commande autrement.

Voici un exemple de mon système:

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

Afin de voir quel fichier a été généré pour la dernière fois lorsque l'alias a été affecté pour déterminer le fichier sur lequel il s'est produit, vous pouvez étendre le grep:

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

Cela peut renvoyer des faux positifs, mais cela devrait être correct si vous inspectez manuellement les données renvoyées. Le nombre de symboles «+» devant la commande exécutée indique la profondeur.

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

Dans cet exemple de sortie, il montre que .bashrc définit un alias pour ls, .foo alias t, puis .bashrc remplace l'alias précédent de t.


Merci. C'est certainement utile, mais pas en mesure de voir comment il trouve le conflit créant des alias.
user13107

@ user13107 J'ai ajouté quelques détails supplémentaires qui devraient être utiles. La définition d'un alias sur une nouvelle valeur n'est pas un alias "en conflit". C'est un comportement documenté normal, c'est pourquoi une méthode de contournement est nécessaire.
jordanm
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.