Можно ли переопределить встроенную в командную строку команду «cd»?

22

Примерно каждый раз, когда я 'cd' в другой каталог на моем компьютере (в данном случае, под управлением Mac OS X 10.6.7) через командную строку (это bash), я сразу же набираю 'ls', чтобы получить список содержимого. в этом каталоге. Я пытаюсь найти способ переопределить 'cd', чтобы он изменился на запрошенный каталог и затем выдал мне список за один раз.

Мне удалось получить базовую функциональность, над которой я работаю, добавив следующую строку в мой ~ / .bash_profile

function cl() { cd "$@"; ls -l; }

Это работает как ожидалось. Перейдя в запрошенный каталог, а затем показывая мне содержимое. Я сталкиваюсь с проблемой, пытаясь переопределить сам «cd» вместо создания новой команды «cl».

Следующие вещи не работают

##### Attempt 1 #####
# Hangs the command line

function cd() { cd "$@"; ls -l; }


##### Attempt 2 #####
# Hangs the command line

function cd() { 'cd' "$@"; ls -l; }


##### Attempt 3 #####
# Does not change directory. 
# Does list contents, but of the directory where you started.

function cd() { /usr/bin/cd "$@"; ls -l; }


#### Other attempts that fail in various ways #####
alias cd=cd "$@"; ls -la;
alias cd="cd '$@'; ls -la;"
alias cd='cd "$@"'; ls -la;
alias cd=/usr/bin/cd "$@"; ls -la;

Я также попробовал несколько других итераций, которые не перечислены, а также создал псевдоним, который указывает на работающую функцию 'cl'. Ни один из которых не работал.

То, что я прочитал в документации, говорит о том факте, что «cd» не может быть запущен как внешняя команда (как я понимаю, это то, как функция должна использовать ее).

Таким образом, в настоящее время я могу использовать свою команду "cl" и получить то, что хочу, но вопрос в том / остается:

Есть ли способ переопределить поведение 'cd', чтобы оно изменилось на запрошенный каталог, а затем сделать что-то еще после этого?

Алан В. Смит
источник

Ответы:

30

Следующее должно работать:

function cd() { builtin cd "$@" && ls -l; }

Поскольку функция находится в одной строке, убедитесь, что она завершена, ;как указано выше, для правильной работы.

багор
источник
Не работает для вызова без параметров.
Даниэль Бек
3
@DanielBeck - по крайней мере, на моем Mac OSX (10.6.7) это работает нормально с вызовом без параметров. Поведение заключается в том, что он меняется на домашний каталог, а затем делает список этого каталога. Эффективно дублирует функциональность простого старого 'cd' с новой функцией, добавленной в конце.
Алан В. Смит
2
@Alan Правда, я проверил это, записав этот код в оболочку. Кажется, что поведение cd ""(то, что этот ответ должен оценить, отличается от cd "$@"пустого $@. Извините за путаницу.
Даниэль Бек
@DanielBeck - не беспокойся.
Алан У. Смит
2
Примечание: я изменяю это на принятый ответ, так как это точный ответ на вопрос. Один из @RichHomolka отлично подходит для обращения к принципалу, но именно этот можно поместить в файл ~ / .bash_profile.
Алан У. Смит
10

Я думаю, что вы попали в петлю. Ваша cdфункция вызывает cd, которая является ... функцией.

Вам нужно знать builtin, какое ключевое слово заставляет поиск команд использовать встроенные функции Bash, такие как cd, а не вашу функцию.

function cd
{
    builtin cd "$1"
    : do something else
}

Кроме того, вызов /usr/bin/cdникогда не будет работать, даже если такая команда существовала.

Что случилось бы:

  • Моя оболочка Bash находится в реж /bash/dir.
  • Я запускаю команду /usr/bin/cd /dir/for/cd.
  • /usr/bin/cdидет в реж /dir/for/cd.
  • /usr/bin/cd выходы.
  • Bash все еще включен /bash/dir, потому что дочерний процесс /usr/bin/cdне может влиять на родительский процесс .

Также псевдонимы - это простые текстовые замены. У них никогда не может быть параметров.

Рич Гомолка
источник
Я предлагаю builtin cd $@ && ls; поскольку cdвызов должен быть успешным, чтобы все остальное имело смысл. Также запомните особые случаи, такие как cd(без аргументов).
Даниэль Бек
Примечание: я пытался пометить это как принятый ответ, но он говорит мне, что мне нужно подождать еще 6 минут, прежде чем я смогу это сделать. Не знал, что была встроенная задержка, прежде чем ты смог сделать это.
Алан В. Смит
@Alan Другое, лучшее решение может прийти в очень разумные сроки (т.е. те несколько минут, которые вам придется подождать). Я думаю, именно поэтому существует задержка системы: вы должны отдавать предпочтение качеству, а не скорости. Это не должно быть слишком много неудобств.
Даниэль Бек
И у нас есть победитель. Это работает как чемпион. Для @DanielBeck я изменил на использование && и сжал его до одной строки с помощью: function cd {builtin cd "$ @" && ls -l; }
Алан В. Смит
@DanielBeck - Да, я не беспокоюсь об этом. Просто никогда не замечал этого раньше. Я вижу в этом логику, просто немного удивил меня.
Алан В. Смит,
6

Я предлагаю не переопределять cd, потому что есть некоторые другие скрипты, угоняющие функцию 'cd', например, rvm. Было бы лучше выбрать другое имя, например, «d», и не указывать тип «встроенный» в вашей функции; в противном случае угонщик не будет функционировать. Я использую код ниже:

function d() { cd "$@" && ls;} 
жировик
источник
Я думал, что это не сработает, хотя, на вопрос ОП.
user305964