Bash one-liner для изменения в каталог, где находится какой-либо файл

Я часто хочу перейти в каталог, где находится конкретный исполняемый файл. Поэтому я хотел бы что-то вроде

cd `which python` 

чтобы перейти в каталог, где установлена команда python. Однако это явно незаконно, так как cd берет каталог, а не файл. Очевидно, есть некоторые regexp-foo, которые я мог бы сделать, чтобы удалить имя файла, но это победило бы точку его простого однострочного.

7 ответов


здесь:

cd $(dirname `which python`)

Edit:

еще проще (фактически протестировано на этот раз):

function cdfoo() { cd $(dirname `which $@`); }

затем "cdfoo python".


чтобы избежать всех этих внешних программ ("dirname" и гораздо хуже, бесполезное, но популярное "which"), возможно, немного переписано:

cdfoo() {
  tgtbin=$(type -P "")
  [[ $? != 0 ]] && {
    echo "Error: '' not found in PATH" >&2
    return 1
  }
  cd "${tgtbin%/*}"
}

Это также исправляет необычное ключевое слово "функция" сверху и добавляет (очень простую) обработку ошибок.

может быть началом для более сфистического решения.


Для сравнения:

zsh:~% cd =vi(:h)
zsh:/usr/bin%

=cmd расширяется до пути к cmd и (: h) является модификатором glob, чтобы взять head

zsh-это только для записи, но мощный.


что-то вроде этого должно сделать трюк :

cd `dirname $(which python)`

одна особенность я использовал аллот-это команда pushd / командой popd. Они поддерживают стек каталогов, так что вам не нужно пытаться сохранить историю того, где вы были, если вы хотите вернуться в текущий рабочий каталог до изменения каталогов.

например:

pushd $(dirname `which $@`)
...
popd

вы можете использовать что-то вроде этого:

cd `which <file> | xargs dirname`

Я добавил немного простой обработки ошибок, которая заставляет поведение cdfoo() следовать за поведением dirname для несуществующих/nonpath аргументов

function cdfoo() { cd $(dirname $(which  || ( echo . && echo "Error: '' not found" >&2 ) ));}