Как проверить наличие возможных конфликтов при использовании псевдонима в bashrc?

12

Есть ли простой способ перечислить все конфликты команд, которые произошли в системе из-за обновления bashrc с использованием команд псевдонимов?

Например, кто-то пишет alias ls=/path/to/user-generated/executableв bashrc. Как узнать, что это маскирует действительную команду ( ls). Один из способов, по-видимому, состоит в том, чтобы запустить все псевдонимы до и после получения bashrc и отразить вывод. Есть ли лучшие способы?

Я использую Ubuntu 12.04.

Баш - версия

GNU bash, версия 4.2.24 (1) -релиз (i686-pc-linux-gnu)

user13107
источник
В качестве примечания, как правило, более полезно, чтобы люди отвечали, если вы предоставляете свою версию bash, а не версию ОС, когда задаете вопрос, относящийся к bash.
Иордания
@jordanm Обновлено.
user13107

Ответы:

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.

choroba
источник
Например, type lsпечатает ls is aliased to `ls --color=auto'здесь.
10
То же самое работает с which, но я не теперь, если обе (тип, который) встроенные оболочки одинаковы.
математика
@math: type whichговорит вам which is /usr/bin/which, так что это не встроенный. Следовательно, он не может сказать вам, является ли что-то встроенным или нет (например, which echoпротив type echo).
Чороба
Я думаю, это зависит от используемой вами оболочки: type which which is a shell builtinя использую zsh.
математика
@math: оригинальный вопрос помечен / bash.
Чороба
7

В качестве первого вопроса нет способа перечислить конфликты, поскольку bash использует внутреннюю хеш-таблицу, она записывает только последнее переопределение.

Чтобы выяснить, является ли команда псевдонимом, используйте alias lsв вашем случае, если она говорит что-то вроде «not found», то это не псевдоним, в противном случае это так.

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

РЕДАКТИРОВАТЬ

Если вы хотите быстро узнать, является ли команда псевдонимом, вы можете включить режим отладки set -x, теперь, если вы выполните ls:

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

Вы увидите отладочный вывод выполняемой команды

Чтобы отключить режим отладки, используйте set -

маргаритка
источник
Благодарю. Но не получил aliasроль. Что если пользователь не знает, что существует команда (например ls)? Единственное, что он, кажется, знает после запуска, alias lsэто то, на что он сопоставлен, а не то, с чем он был изначально сопоставлен. Я думаю, что нужно будет выполнить все команды с и без \, чтобы найти конфликты.
user13107
@ user13107 обновил ответ
маргаритка
Благодарю. Как отключить трассировку?
user13107
@ 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выводит только те строки, которые являются общими для обоих.

CAMH
источник
5

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

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

Выполнение команды exit необходимо для возврата оболочки. В -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 alias t, а затем .bashrc переопределяет предыдущий псевдоним t.

jordanm
источник
Благодарю. Это, безусловно, полезно, но не в состоянии увидеть, как он находит конфликт, создавая псевдонимы.
user13107
@ user13107 Я добавил еще несколько деталей, которые должны быть полезны. Установка псевдонима в новое значение не является «конфликтующим» псевдонимом. Это нормальное документированное поведение, поэтому необходим обходной путь.
Иордания