Псевдоним 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.