tags:

views:

274

answers:

7

I often want to change to the directory where a particular executable is located. So I'd like something like

cd `which python`

to change into the directory where the python command is installed. However, this is obviously illegal, since cd takes a directory, not a file. There is obviously some regexp-foo I could do to strip off the filename, but that would defeat the point of it being an easy one-liner.

+14  A: 

Here:

cd $(dirname `which python`)

Edit:

Even easier (actually tested this time):

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

Then "cdfoo python".

Lance Richardson
+1 We are not worthy.
Thomas L Holaday
I should have stopped when I was ahead... edited to delete bogus alias form.
Lance Richardson
nice... make a function...+1
ojblass
Nesting $() works: function cdfoo() { cd $(dirname $(which $@)); }
Dennis Williamson
This doesn't work for programs with spaces in them (though anyone who uses such programs in *nix should be shot); that can be fixed by putting double quotes around the $@.
Adam Rosenfield
Actually, scratch that, even with the quotes, 'which' chokes, since it apparently it re-tokenizes its arguments.
Adam Rosenfield
`which` sucks. And no quotes sucks too. And using $@, especially unquoted, when only one argument is allowed, sucks too. cdto() { local to=$(type -P "$1"); cd "${to%/*}"; }
lhunath
How about `cdfoo() { cd "$(dirname "$(type -p "$*")")"; }`, which should handle spaces?
ephemient
+2  A: 

something like that should do the trick :

cd `dirname $(which python)`
Thomas Levesque
+1  A: 

You could use something like this:

cd `which <file> | xargs dirname`
Rob Carr
+2  A: 

One feature I've used allot is pushd / popd. These maintain a directory stack so that you don't have to try to keep history of where you were if you wish to return to the current working directory prior to changing directories.

For example:

pushd $(dirname `which $@`)
...
popd
Kam
+7  A: 

To avoid all those external programs ('dirname' and far worse, the useless but popular 'which') maybe a bit rewritten:

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

This also fixes the uncommon keyword 'function' from above and adds (very simple) error handling.

May be a start for a more sphisticated solution.

TheBonsai
+1, What a relief, there is sanity left in the UNIX world.
lhunath
A: 

I added a bit of simple error handling that makes the behavior of cdfoo() follow that of dirname for nonexistent/nonpath arguments

function cdfoo() { cd $(dirname $(which $1 || ( echo . && echo "Error: '$1' not found" >&2 ) ));}
Dennis Williamson
+3  A: 

For comparison:

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

=cmd expands to the path to cmd and (:h) is a glob modifier to take the head

zsh is write-only but powerful.

Phil P
Thank you for the code. They are outstanding!
Masi