Страницы

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

воскресенье, 16 февраля 2020 г.

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

#linux #bash


Хотел сделать алиас 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 перечисляет список директорий / файлов
по пути /, так почему же тогда он возвращает обратно в домашнюю директорию?
    


Ответы

Ответ 1



псевдоним оболочки (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. правильнее передавать не только первый аргумент, а все аргументы ($@), а чтобы корректно обрабатывались спец-символы (например, пробелы/кавычки и т.п.) внутри аргументов, список лучше заключить в двойные кавычки ("$@").

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

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