Jak przetestować możliwe konflikty podczas używania aliasu w bashrc?

12

Czy istnieje prosty sposób na wyświetlenie listy wszystkich konfliktów poleceń, które wystąpiły w systemie z powodu aktualizacji bashrc obejmującej polecenia aliasu?

Na przykład ktoś pisze alias ls=/path/to/user-generated/executablew języku bashrc. Jak dowiadujemy się, że to maskuje rzeczywiste polecenie ( ls). Jednym ze sposobów wydaje się być uruchomienie wszystkich aliasów przed i po sashcingu bashrc i różnicowanie wyniku. Czy są jakieś lepsze sposoby?

Używam Ubuntu 12.04.

bash --version

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

użytkownik13107
źródło
Na marginesie, zwykle jest bardziej pomocne dla osób odpowiadających, jeśli podasz swoją wersję bash, niż wersję systemu operacyjnego, gdy zadajesz pytanie specyficzne dla bash.
jordanm
@jordanm Zaktualizowano.
user13107,

Odpowiedzi:

8

Aby dowiedzieć się, które polecenia są maskowane przez aliasy, wykonaj następujące czynności:

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

Wyjaśnienie

aliassam wyświetla listę zdefiniowanych aliasów i sedwypakowuje ich nazwy. Pętla while działa type -tana każdym z nich i awkdrukuje linie zawierające zarówno alias, jak i plik.

Thor
źródło
15

Możesz użyć, typeaby dowiedzieć się, jak polecenie będzie interpretowane przez bash.

choroba
źródło
Na przykład type lsdrukuje ls is aliased to `ls --color=auto'tutaj.
l0b0
To samo działa which, ale nie mam teraz, jeśli oba wbudowane powłoki (typ, który) są takie same.
matematyka
@math: type whichmówi which is /usr/bin/which, więc nie jest to wbudowane. Dlatego nie można powiedzieć, czy coś jest wbudowane, czy nie (np. W which echoporównaniu z type echo).
choroba
Myślę, że to zależy od używanej powłoki: type which which is a shell builtinużywam zsh.
matematyka
@ matematyka: Oryginalne pytanie jest oznaczone / bash.
choroba
7

Jako pierwsze pytanie nie ma sposobu, aby wyświetlić listę konfliktów, ponieważ bash korzysta wewnętrznie z tabeli skrótów, rejestruje tylko ostatnie przesłonięcie.

Aby dowiedzieć się, czy polecenie jest aliasem, użyj alias lsw swoim przypadku, jeśli mówi coś w stylu „nie znaleziono”, to nie jest to alias, w przeciwnym razie jest.

Aby uruchomić oryginalną funkcję bez względu na alias, prefiks ukośnika, np. \lsUruchomi prawdziwy haszowany ls, zignoruj ​​alias.

EDYTOWAĆ

Jeśli chcesz szybko dowiedzieć się, czy polecenie jest aliasem, możesz włączyć tryb debugowania do set -x, teraz, jeśli wykonasz ls:

wprowadź opis zdjęcia tutaj

Zobaczysz wyjście debugowania wykonywanego polecenia

Aby wyłączyć tryb debugowania, użyj set -

stokrotka
źródło
Dzięki. Ale nie dostałem aliasroli. Co jeśli użytkownik nie wie, że istnieje polecenie (np. ls)? Jedyne, co wydaje się wiedzieć po uruchomieniu, alias lsto to, do czego jest mapowane, a nie to, z czym było pierwotnie mapowane. Myślę, że trzeba będzie uruchomić wszystkie polecenia zi bez \, aby znaleźć konflikty.
user13107,
@ user13107 zaktualizował odpowiedź
stokrotka
Dzięki. Jak mogę wyłączyć śledzenie?
user13107,
@ użytkownik13107 zaktualizowany ponownie ;-P
stokrotka
1
„nie ma sposobu, aby wymienić konflikty” - po prostu nie masz dość wyobraźni.
camh
6

Możesz użyć wbudowanego basha, compgenaby uzyskać listę wszystkich używanych poleceń i wszystkich aliasów compgen -ac. Każde polecenie, które jest również aliasem, zostanie powielone na tej liście, więc prostym naiwnym rozwiązaniem jest poszukiwanie duplikatów na wyjściu compgen -ac.

Jednak duplikaty mogą się również pojawić, jeśli polecenie znajduje się dwukrotnie na ścieżce. Na przykład mam /bin/whichi /usr/bin/whichtak compgen -acwymienię whichdwa razy, mimo że nie jest to alias.

Potrzebne jest więc pobranie wszystkich duplikatów compgen -aci porównanie ich z listą aliasów. Jedynymi duplikatami, które są również aliasami, są te aliasy, które ukrywają polecenia. Możemy to zrobić za pomocą comm(1)polecenia i podstawienia procesu bash.

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

compgen -a | sortjest listą wszystkich aliasów (posortowanych comm). compgen -ac | sort | uniq -dto lista wszystkich duplikatów z listy poleceń i aliasów. comm -12wyprowadza tylko te linie, które są wspólne dla obu.

camh
źródło
5

Możesz użyć funkcji debugowania powłoki, aby zobaczyć dokładnie, co się dzieje, gdy bash wywołuje interaktywną powłokę. Poniższe informacje powinny pokazywać wszystkie aliasy przypisane podczas odradzania się powłoki interaktywnej z powłoki logowania:

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> włącz debugowanie
  • -l -> powłoka logowania
  • -i -> interaktywna powłoka
  • -c -> polecenie

Uruchomienie polecenia exit jest wymagane, aby powłoka powróciła. Jest -ito wymagane w tym przypadku, ponieważ bash nie skonfigurowałby środowiska interaktywnego do uruchomienia polecenia w przeciwnym razie.

Oto przykład z mojego systemu:

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

Aby zobaczyć, który plik był ostatnio pozyskiwany, gdy został przypisany alias w celu ustalenia pliku, w którym wystąpił, możesz rozszerzyć grep:

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

Może to zwracać wyniki fałszywie dodatnie, ale powinno być w porządku, jeśli ręcznie sprawdzasz zwrócone dane. Liczba symboli „+” przed wykonanym poleceniem wskazuje głębokość.

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

W tym przykładzie wyjściowym pokazano, że .bashrc ustawia alias dla ls, .foo aliasy t, a następnie .bashrc zastępuje poprzedni alias t.

Jordan
źródło
Dzięki. Jest to z pewnością przydatne, ale nie jest w stanie zobaczyć, jak rozpoznaje konflikt, tworząc aliasy.
user13107,
@ user13107 Dodałem więcej szczegółów, które powinny być pomocne. Ustawienie nowej wartości aliasu nie jest aliasem „powodującym konflikt”. Jest to normalne, udokumentowane zachowanie, dlatego potrzebny jest okrągły sposób.
jordanm