Tag Info

Hot answers tagged

38

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 ...


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'


9

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. ...


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 ...


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

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 ...


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

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 ...


7

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). ...


7

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.


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 ...


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

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 ...


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

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

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

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 ...


3

You generally don't want to use the which command. In Bash you should be using the type or command commands. See this Q&A for reasons why, titled: Why not use “which”? What to use then?. Examples $ type -a ls ls is aliased to `ls --color=auto' ls is /bin/ls or this: $ type -a vim vim is /usr/bin/vim or this: $ command -v ls alias ls='ls ...


3

Explicitly setting the value of $PATH in the sub-shell resolves the problem: env -i sh -c "PATH=\$PATH which ruby" Note that the $ in $PATH is escaped, which means that $PATH in the sub-shell command isn't substituted with the parent shell's value of $PATH before the command is executed (this could also be achieved using single quotes). I'd be really ...


3

This sounds like your package database is screwed up. First I'd identify all the versions of xdg-open that you have on your system. The type should always be used for doing this task, never rely on which or whereis. Example Identify all xdg-open's. $ type -a xdg-open xdg-open is /usr/bin/xdg-open Find out which packages they're a part of. $ dpkg -S ...


3

That would mean that if output for which does not refer to a terminal, then do not process --read-alias, --show-dot and --show-tilde. Typically if to a pipe, ordinary file etc. which watch | foo # not a tty which watch > foo # not a tty which watch # tty which watch >&2 # tty The options are not recognized under e.g. debian:


3

You should use the type command to know what is really under its name, i.e.: type cmake That might be an alias that run a different version of cmake, or a function with a similar behavior or finally a previously hashed command that in not any more the first one in your PATH, as you experienced.


3

Most likely it doesn't work for you because the shell builtin is getting executed with priority over any executable. You should not knowingly create a name conflict like this, behavior will be inconsistent across environments. The system binary test is only there for the use of shells that don't have a builtin version. If you want alternate functionality, ...


3

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" ...


3

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, ...


2

As the hint says, and quoting from the manual page, "Which takes one or more arguments. For each of its arguments it prints to stdout the full path of the executables that would have been executed when this argument had been entered at the shell prompt. It does this by searching for an executable or script in the directories listed in the environment ...


2

which rvm looks for an executable called rvm. That executable only outputs the “RVM is not a function …” message when run. rvm is probably a function, or perhaps an alias, in your shell. It has been defined in your ~/.bashrc (or in the system-wide /etc/bash.bashrc or in a file included from one of these). To see what the rvm command is, run type rvm or ...


1

You can search the $PATH yourself to find a command: COMMAND=vim # This is the command to search for (IFS=:; for dir in $PATH; do [ -x $dir/$COMMAND ] && echo $dir/$COMMAND; done) (this should work in ash and many other Bourne shell derivatives)


1

According to the which man page, which searches components of the PATH variable using the same algorithm as bash, that is each component of PATH is searched in turn. So, as you observed, which (without the -a) will just show you the first match found in PATH. Your example is somewhat peculiar in that which returns what would not be the "primary executable", ...



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