Как отменить автоматический вызов pushd и popd для dirs?
Мой bash
(4.1) В стеке каталогов обычно содержится десяток или более записей. Я хотел заменить вывод dirs
с dirs -v
так что мне никогда не пришлось бы играть "угадать магическое число" с pushd
снова.
Мое Частичное Решение
Я заменил dirs
с функцией, которая выполняется dirs -v
с помощью command
:
dirs()
{
# "command" builtin prevents infinite recusion by suppressing lookup
# of function and alias names.
command dirs -v "${@}"
}
(Обновление: по предложению пневматики, я сейчас использую builtin
вместо command
, Это не решает эту проблему, но это немного безопаснее.)
dirs
вывод был теперь читабелен, но pushd
а также popd
до сих пор выпускает старую рвотную косую черту:
$ pushd ~/just/one/more/and/ill/quit/i/promise
~/just/one/more/and/ill/quit/i/promise ~/tmp/bash/bash-4.1...
may/give/rise/to/dom /oh/no/not/again /var/adm/log /omg/wt...
va/lang ~/doc/comp/java/api/java/util/regex barf barf barf...
Я получил тот же (отсутствие) результат после замены моего dirs
функция с псевдонимом:
alias dirs='command dirs -v "${@}"'
Обходной путь
В конце концов я получил желаемый результат, переопределив pushd
а также popd
также:
pushd()
{
command pushd "${@}" >/dev/null &&
dirs
}
# popd is similar.
Это работает, но требует переопределения трех встроенных функций вместо одной. Кроме того, это может быть несовершенным олицетворением pushd
а также popd
в каком-то угловом случае я не подумал. Я бы предпочел переопределить dirs
только.
Мой вопрос
Почему не переопределить dirs
Работа? В соответствии с bash
"s man
страница под обоими pushd
а также popd
:
Если
pushd
команда успешна,dirs
также выполняется.
Так почему же pushd
а также popd
кажется, чтобы вызвать встроенный dirs
вместо функции или псевдонима?
Сноска о bash
Документация
Абзацы, говорящие "а dirs
выполняется также "отсутствуют в bashref.*
онлайн руководство, но они появляются в man
страницы bash.*
а также builtins.*
, Оба мои bash
Документы 4.1 и текущие документы 4.4 противоречивы в одном и том же порядке, что говорит о том, что 4.4 (если бы он у меня был) вел себя одинаково.
2 ответа
Из моего прочтения исходного кода bash оба pushd
а также popd
позвонить dirs
встроенный сам (без каких-либо аргументов), вместо обращения к определенным псевдонимам и функциям.
Хотя кажется, что встроенная функция использует внешнюю функциональность редко, когда встроенная функция нуждается во внешней функции, вызов другой встроенной функции кажется прецедентом. Например, когда pushd
меняет каталог, вызывает cd
встроенный Или когда declare
нужно набрать приведение переменной, он вызывает set
встроенный
Как обойти это? Ну, можно перекомпилировать bash из исходного кода: было бы тривиально pushd
а также popd
пройти -v
аргумент. Можно также попросить bash upstream добавить переменную окружения, которая определяет значение по умолчанию dirs
варианты при использовании в качестве помощника pushd
/ popd
, Но кажется, что самое быстрое решение для пользователей - то, что вы сделали: просто переопределите все три.
Вы хотите использовать builtin
вместо command
, Я думаю, что это то, что вы после, переопределяет pushd
а также popd
, оставляя dirs
как есть.
pushd(){ builtin pushd "$@" >/dev/null && dirs -v; }
popd() { builtin popd "$@" >/dev/null && dirs -v; }