Страницы

Поиск по вопросам

суббота, 27 апреля 2019 г.

Почему алиас «cd» работает так странно?

Хотел сделать алиас cd, который будет сразу перечислять директории.
Попробовал все следующие варианты:
alias 'cd'='cd $1; l' alias 'cd'='cd $1; l $1' alias 'cd'='cd $1 && l' alias 'cd'='cd $1 && l $1'
Где, l (строчная «L») — алиас другого приложения (tree).
Всегда перегружал терминал, чтобы наверняка, так как . ~/.bash_aliases у меня почему-то не срабатывает.
Все вышеперечисленные алиасы при вводе cd / перечисляют список директорий / файлов в точке монтирования /, однако смена директории не происходит.
Тогда я попробовал прописать в том же .bash_aliases функцию (оба варианта, по очереди):
cd() { cd $1 l }
function cd() { cd $1 l }
В итоге, при выполнении cd / команда «виснет» ...
Единственный способ, который я нашёл, это сделать так:
cdl() { cd $1 l }
То есть задать другое имя ... Но в тоже время, если вернуться к первому варианту алиаса:
alias 'cd'='cd $1; l'
Здесь же срабатывает cd при вводе cd /, так как l перечисляет список директорий / файлов по пути /, так почему же тогда он возвращает обратно в домашнюю директорию?


Ответ

псевдоним оболочки (shell alias) — это не функция и не программа. у псевдонима нет аргументов, его описание всего лишь подставляется в команду вместо его имени. поэтому, если вы определили, например, такой псевдоним
$ alias cd='cd $1; ls'
то при вводе команды
$ cd /tmp
она преобразуется в
$ cd ; ls /tmp
обратите внимание на пустое место после cd — туда ничего не будет подставлено (вместо $1), т.к. переменная $1 не содержит никакого значения.
в результате вашим текущим каталогом станет ваш домашний каталог (так действует внутренняя команда cd, если ей не передать никаких параметров), а затем будет выполнена команда ls /tmp когда вы определяете функцию:
$ function cd() { cd $1; ls; }
команда cd $1 внутри её тела трактуется как рекурсивное обращение к этой же функции, вот и происходит «зависание». кстати, обратите внимание, что в теле псевдонима не происходит такой рекурсии — cd $1 там трактуется именно как обращение к внутренней команде оболочки cd

и напоследок, в виде факультативного дополнения к ответу на вопрос «почему», приведу пример того, как сделать, чтобы «работало так, как хочется»:
$ function cd() { command cd "$@"; ls; }
использовать надо именно функцию (кстати, само ключевое слово function в данном случае — опционально), чтобы получить и обработать список аргументов. для вызова внутренней команды оболочки надо использовать внутреннюю же команду command правильнее передавать не только первый аргумент, а все аргументы ($@), а чтобы корректно обрабатывались спец-символы (например, пробелы/кавычки и т.п.) внутри аргументов, список лучше заключить в двойные кавычки ("$@").

Комментариев нет:

Отправить комментарий