Tag Info

Hot answers tagged

91

A common question, glad you asked it here. Here is all you never thought you would ever not want to know about it. Summary To get the pathname of an executable in a Bourne-like shell script (there are a few caveats; see below): ls=$(command -v ls) To find out if a given command exists: if command -v given-command > /dev/null 2>&1; then echo ...


44

which is actually a bad way to do things like this, as it makes guesses about your environment based on $SHELL and the startup files (it thinks) that shell uses; not only does it sometimes guess wrong, but you can't generally tell it to behave differently. (which on my Ubuntu 10.10 doesn't understand --skip-alias as mentioned by @SiegeX, for example.) type ...


13

Use dirname: cd "`dirname $(which program)`"


11

It's because your root user has a different path. sudo echo $PATH prints your path. It's your shell that does the variable expansion, before sudo starts (and passes it as a command line argument, expanded). Try: sudo sh -c 'echo $PATH'


11

That line in your .profile should be one of export PATH="$PATH:$HOME/Unix/homebrew/bin" PATH="$PATH:$HOME/Unix/homebrew/bin" PATH=$PATH:$HOME/Unix/homebrew/bin PATH=$PATH:~/Unix/homebrew/bin The ~ character is only expanded to your home directory when it's the first character of a word and it's unquoted. In what you wrote, the ~ is between double quotes ...


10

In the 21st century, especially if you're targeting machines that are likely to have bash or zsh, you can count on type being available. (It didn't exist in extremely old unices, as in, from the 1970s or early 1980s.) You can't count on its output meaning anything, but you can count on its returning 0 if there is a command by that name and nonzero otherwise. ...


10

The reasons why one may not want to use which have already been explained, but here are a few examples on a few systems where which actually fails. On Bourne-like shells, we're comparing the output of which with the output of type (type being a shell builtin, it's meant to be the ground truth, as it's the shell telling us how it would invoke a command). ...


9

I would use type instead of which, because which is unreliable (as you noticed; unless it's a shell builtin, it has to guess at your environment).


9

Check your path. It's not that hard to end up with duplicates in it. Example: »echo $PATH /usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin: »which -a bash /bin/bash /usr/bin/bash This is because my /bin is a symlink to /usr/bin. Now: »export PATH=$PATH:/usr/bin »echo $PATH /usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/bin »which -a ...


9

One thing which (from my quick skim) it seems that Stephane didn't mention is that which has no idea about your shell's path hash table. This has the effect that it might return a result which is not representative of what actually is run, which makes it ineffective in debugging.


8

zsh is one of the few shells (the other ones being tcsh (which originated as a csh script for csh users, which also had its limitation, tcsh made it a builtin as an improvement)) where which does something sensible since it's a shell builtin, but somehow you or your OS (via some rc file) broke it by replacing it with a call to the system which command which ...


8

The three possibilities that come to mind for me: An alias exists for emacs (which you've checked) A function exists for emacs The new emacs binary is not in your shell's PATH hashtable. You can check if you have a function emacs: bash-3.2$ declare -F | fgrep emacs declare -f emacs And remove it: unset -f emacs Your shell also has a PATH hashtable ...


8

Setup: $ /usr/bin/which --show-dot a ./a $ /usr/bin/which --show-tilde a ~/a If you wanted the . version when run interactively, but the ~ version when redirected, you would could use this as an alias: /usr/bin/which --show-tilde --tty-only --show-dot Demo: # interactive / on a tty $ /usr/bin/which --show-tilde --tty-only --show-dot a ./a # not ...


7

Either create an alias to it in your shell, or put its directory ahead of the other in $PATH.


7

executable=mysql executable_path=$(command -v -- "$executable") && dirname -- "$executable_path" (don't use which). Of course, that won't work if $executable is a shell builtin, function or alias. I'm not aware of any shell where mysql is a builtin. It won't be a function or alias unless you defined them earlier, but then you should know about ...


6

I would guess that you have /home/sawa/foo/bar/ on your path - i.e. a path with a trailing slash. which is iterating over each element of $PATH and appending /argv[1] and checking for the existence of that file. That causes a double-slash - one from the $PATH part, and one from /argv[1]. A double-slash is no problem. It is collapsed to a single slash by ...


6

The one that gets output when you run which without -a is the one which will get executed. (and the second one with -a is preferred over the third one). This doesn't take into account the shell's builtins, aliases, and functions which will run (from within the shell) before any other executable. Therefore, it's better to use type instead.


6

Use type, which is internal to bash. $ type vim vim is /usr/bin/vim $ type -p vim /usr/bin/vim $ alias vim="echo mwahaha" $ type vim vim is aliased to `echo mwahaha' $ type -p vim $ There's a good breakdown of the different ways to get information about a command in this answer by Stephane Chazelas. You shouldn't rely on which, even non-maliciously, it ...


5

man -w will print the path to manpage. ldd may do the trick for libraries, run it on the executable that's linked against them.


5

command -pv uses a "default value for PATH". $ which ruby /home/mikel/.rvm/rubies/ruby-1.9.3-p484/bin/ruby $ command -pv ruby /usr/bin/ruby Unfortunately that doesn't work in zsh, so based on Stephane's comment, we could use getconf PATH: $ PATH=$(getconf PATH) which ruby or use command -v in place of which, as recommended in Why not use ...


5

This should be a standard solution: type type -t type -p


4

This is happening because ~ has not been expanded. Your shell knows how to deal with this, but which does not (nor would most other programs). Instead, do: export "PATH+=:$HOME/Unix/homebrew/bin" Alternatively, stop using which, and use the (almost always superior) type -p. Here is a demonstration of the issue: $ echo "$PATH" ...


4

If you want to switch between them on the fly, without changing your $PATH, here's a little pattern I have used over the years, after seeing a coworker use this to good effect. I assume you have a $HOME/bin already, really early in your $PATH. Create the following shell script there, #/bin/sh PATH="/usr/local/bin:$PATH" export PATH exec ${1+"$@"} called, ...


4

The one that shows with only which python is the one your console will use, unless you have python aliased to something else (alias python='/usr/bin/python').


4

In bash: type -P vim In zsh: type -p vim In both: /usr/bin/which vim Or: ( unalias vim; type vim )


4

In bash, I recommend type -p over which. which is an external command and it's tricky at times. You can use sed to remove everything after the final /, or use the special-purpose dirname utility. cd "$(dirname -- "$(type -p program)")" cd "$(type -p program | sed 's:[^/]*$::')" On the command line, if you know that the directory doesn't contain any ...


4

Yes, don't use which: On some systems, it's an external command implemented as a csh script, which may read a configuration that changes the PATH. There's a builtin for that. Two, even: type and command. The POSIX way: command -v emacs # machine-readable format type emacs # human-only format In bash, you can also use type -p emacs to ...


4

which In general this command should be avoided. Why? Because it uses your current environment when constructing the $PATH that it's going to evaluate when looking for executables. This can lead to confusion when dealing with shell scripts and such, that will potentially be using the $PATH as constructed by your ~/.bashrc and ~/.bash_profile files when ...


4

With zsh (note that which is only built in tcsh or zsh, in other shells it can give random results, use type in Bourne like shells): $ which -m '*latex' /usr/bin/arlatex /usr/bin/dvilualatex /usr/bin/fig4latex /usr/bin/latex /usr/bin/lualatex /usr/bin/pdflatex /usr/bin/pod2latex /usr/bin/pslatex Or (if you only want to consider executables and not ...


4

In a shell command like PATH=~/bin:/opt/texbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games the tilde is expanded to your home directory when the shell command is executed. Thus the resulting value of PATH is something like /home/theconjuring/bin:/opt/texbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games. Make sure that the tilde ...



Only top voted, non community-wiki answers of a minimum length are eligible