Псевдоним Bash - приоритет / затенение (/ скрытие / сбой)
У меня есть несколько настроек псевдонимов (в этом порядке) в .bashrc:
alias ls="lsc"
alias lsc='ls -Flatr --color=always'
alias lscR='ls -FlatrR --color=always'
Подтверждение их alias
после поиска:
alias ls='lsc'
alias lsc='ls -Flatr --color=always'
alias lscR='ls -FlatrR --color=always'
Я могу просто запустить новый псевдоним ls
, и он будет связан с псевдонимом lsc, а затем выполнит команду, связанную с псевдонимом lsc. Я тоже могу бегать, lscR
и все работает как положено.
Если я попытаюсь запустить lsc
сам себя, то получу:
$ lsc
lsc: command not found
Есть идеи, почему оболочка, кажется, скрывает / скрывает псевдоним lsc в этом сценарии? (Я понимаю, что запускать lsc бессмысленно, если я могу просто запустить ls, чтобы получить тот же результат, но я пытаюсь понять поведение оболочки в этом сценарии).
РЕДАКТИРОВАТЬ: нижеприведенные обходные пути для поведения оболочки (bash), указанные в ответах на вопросы.
На исходный вопрос было дано несколько действительно полезных ответов. Чтобы сократить поведение расширения, которое объясняется в ответах, кажется, есть как минимум два способа предотвратить вторым псевдонимом, пытаясь расширить команду, на которую вы уже указали псевдоним. Например, если у вас есть alias cmd='cmd --stuff'
команда cmd
, которая переопределяет вызываемую собственную команду , вы можете предотвратить использование псевдонима cmd вместо собственного cmd
в других псевдонимах:
(спасибо комментарию wjandrea за этот первый подход)
- с префиксом
cmd
'command' в другом псевдониме, напримерalias other-cmd-alias='command cmd --other-stuff'
или же,
- Точно так же вы можете экранировать псевдонимы (как и в командной строке) внутри других псевдонимов, добавив префикс с обратной косой чертой '', например
alias other-cmd-alias='\cmd --other-stuff'
.
Ответы
Bash действительно позволяет псевдонимам содержать псевдонимы, но имеет встроенную защиту от бесконечных циклов. В вашем случае, когда вы печатаете lsc
, bash сначала расширяет псевдоним до:
ls -Flatr --color=always
Поскольку ls
это также псевдоним, bash расширяет его до:
lsc -Flatr --color=always
lsc
является псевдонимом, но, вполне разумно, bash отказывается расширять его во второй раз . Если бы была названа программа lsc
, bash запустил бы ее. Но нет, и поэтому вы получаете command not found
.
Дополнение
Другое дело, когда lscR
бежит. lscR
расширяется до:
ls -FlatrR --color=always
Поскольку ls
это псевдоним, он расширяется до:
lsc -FlatrR --color=always
Поскольку lsc
это псевдоним, он расширяется до:
ls -Flatr --color=always -FlatrR --color=always
Поскольку ls
уже был расширен один раз, bash отказывается расширять его второй раз . Поскольку настоящая вызываемая команда ls
существует, она запускается.
История
Как отметил Шили в комментариях, bash позаимствовал концепцию отказа от расширения псевдонима второй раз у ksh .
В сторону
Псевдонимы полезны, но не очень эффективны. Если вы хотите сделать что-то сложное с псевдонимом, например, подстановку аргументов, не делайте этого; вместо этого используйте функцию оболочки.
Из руководства bash :
Первое слово замещающего текста проверяется на псевдонимы, но слово, идентичное расширяемому псевдониму, не раскрывается во второй раз. Это означает, что можно использовать псевдоним , например,
ls
для "ls -F
", и Bash не пытается рекурсивно расширять замещающий текст.
В ls
псевдониме ls
расширяется до, lsc
а затем снова до ls -Flatr --color=always
, и на этом расширение псевдонима останавливается, поскольку ls
изначально расширялось. Итак, команда работает нормально, ls
теперь она преобразована во внешнюю команду.
В lsc
псевдониме, lsc
расширяются до ls -Flatr --color=always
, а затем ls
в настоящее время расширен до lsc
и есть остановки расширения псевдонима, так как lsc
было первоначально расширяются. Итак, команда не работает, поскольку bash не знает других lsc
.