Як перевірити можливі конфлікти під час використання псевдоніма у bashrc?


12

Чи є простий спосіб перерахувати всі конфлікти команд, які виникли в системі через оновлення bashrc, що включає команди псевдонімів?

Наприклад, хтось пише alias ls=/path/to/user-generated/executableв bashrc. Як дізнатися, що це маскування фактичної команди ( ls). Одним із способів, здається, є запуск усіх псевдонімів до і після пошуку bashrc та розходження результатів. Чи є кращі способи?

Я запускаю Ubuntu 12.04.

bash --версія

GNU bash, версія 4.2.24 (1) -випуск (i686-pc-linux-gnu)


Як бічна примітка, зазвичай корисніше людям відповідати, якщо ви надаєте свою версію bash, а не версію ОС, коли задаєте питання, характерне для bash.
Йорданм

@jordanm Оновлено.
користувач13107

Відповіді:


8

Щоб дізнатися, які команди замасковані псевдонімами, зробіть щось подібне:

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

Пояснення

aliasокремо перелічує визначені псевдоніми та sedвитягує їх ім’я. Цикл while працює type -taна кожному з них і awkдрукує рядки, що містять псевдонім і файл.


15

Ви можете використовувати, typeщоб дізнатися, як команда інтерпретується bash.


Наприклад, type lsдрукує ls is aliased to `ls --color=auto'тут.
l0b0

Те саме працює і з цим which, але я зараз не знаю, якщо обидві (тип, які) вбудовані оболонки однакові.
математика

@math: type whichкаже вам which is /usr/bin/which, значить, це не вбудований. Тому він не може сказати вам, чи є щось вбудованим чи ні (наприклад, which echoпроти type echo).
choroba

Я думаю, це залежить від оболонки, яку ви використовуєте: type which which is a shell builtinя використовую zsh.
математика

@math: оригінальне запитання позначено тегами / bash.
choroba

7

Як ваше перше питання, немає ніякого способу перерахувати конфлікти, оскільки bash використовує хеш-таблицю внутрішньо, вона записує лише останню переопрацювання.

Щоб дізнатись, чи є команда псевдонімом, використовуйте alias lsу своєму випадку, якщо вона говорить вам щось на зразок "не знайдено", то це не псевдонім, інакше це.

Щоб запустити оригінальну функцію, не зважаючи на псевдонім, приставте косу рису, наприклад \ls, запустіть справжній хеш-код, ігноруйте псевдонім.

EDIT

Якщо ви хочете швидко дізнатися, чи є команда псевдонімом, ви можете ввімкнути режим налагодження шляхом set -x, якщо ви виконаєте ls:

введіть тут опис зображення

Ви побачите вихід налагодження реальної команди, що виконується

Щоб вимкнути режим налагодження, використовуйте set -


Дякую. Але не взяв aliasучасть. Що робити, якщо користувач не знає, що існує команда (наприклад ls)? Єдине, що він, здається, знає після запуску, alias lsце те, на що це відображено, а не те, з чим він був спочатку відображений. Гадаю, для знаходження конфліктів доведеться запускати всі команди з і без \.
користувач13107

@ user13107 оновив відповідь
Дейзі

Дякую. Як вимкнути трасування?
користувач13107

@ user13107 оновлено знову ;-P
ромашка

1
"немає ніякого способу перелічити конфлікти" - ви просто недостатньо уявні.
camh

6

Ви можете використовувати bash вбудований, compgenщоб отримати список всіх команд та всіх псевдонімів, що використовуються compgen -ac. Будь-яка команда, яка також є псевдонімом, буде дублюватись у цьому списку, тому простим наївним рішенням є пошук дублікатів на виході compgen -ac.

Однак дублікати можуть також з’являтися, якщо команда двічі перебуває на шляху. Наприклад, у мене є /bin/whichі /usr/bin/whichтак compgen -acбуде перераховано whichдвічі, хоча це не псевдонім.

Отже, що потрібно - це отримати всі дублікати compgen -acта порівняти їх із списком псевдонімів. Тільки дублікати, які також є псевдонімами, - це ті псевдоніми, які приховують команди. Ми можемо це зробити за допомогою comm(1)команди та з заміною процесу bash.

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

compgen -a | sort- це список усіх псевдонімів (відсортований за comm). compgen -ac | sort | uniq -d- це список усіх дублікатів зі списку команд і псевдонімів. comm -12виводить лише ті рядки, які є спільними для обох.


5

Ви можете скористатися функцією налагодження оболонки, щоб побачити, що саме відбувається, коли bash викликає інтерактивну оболонку. Далі слід показати всі псевдоніми, які присвоюються, коли інтерактивна оболонка породжена з оболонки для входу:

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> включити налагодження
  • -l -> оболонка для входу
  • -i -> інтерактивна оболонка
  • -c -> команда

Запустити вихід команди потрібно, щоб оболонка повернулася. У -iцьому випадку потрібно, тому що bash не створив б інтерактивне середовище для запуску команди в іншому випадку.

Ось приклад з моєї системи:

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

Для того, щоб побачити, який файл востаннє отримувався, коли псевдонім був призначений для визначення файлу, який він відбувся, ви можете продовжити grep:

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

Це може повернути помилкові позитиви, але має бути добре, якщо ви вручну перевіряєте повернуті дані. Кількість символів "+" перед виконаною командою вказує глибину.

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

У цьому вихідному прикладі видно, що .bashrc встановлює псевдонім для ls.foo псевдонімів t, а потім .bashrc переосмислює попередній псевдонім t.


Дякую. Це, безумовно, корисно, але не в змозі побачити, як він знаходить конфлікт, створюючи псевдоніми.
користувач13107

@ user13107 Я додав ще кілька деталей, які можуть бути корисними. Встановлення псевдоніма новим значенням не є "конфліктним" псевдонімом. Це нормальна документально підтверджена поведінка, саме тому потрібен обхідний шлях.
Йорданм
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.