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
uses the current shell environment instead of poking at your config files, and can be told to ignore parts of that environment, so it shows you what will actually happen instead of what would happen in a reconstruction of your default shell.
In this case, type -P
will bypass any aliases or functions:
$ type -P vim
/usr/bin/vim
You can also ask it to peel off all the layers, one at a time, and show you what it would find:
$ type -a vim
vim is aliased to `vim -X'
vim is /usr/bin/vim
(Expanding on this from the comments:)
The problem with which
is that it's usually an external program instead of a shell built-in, which means it can't see your aliases or functions and has to try to reconstruct them from the shell's startup/config files. (If it's a shell built-in, as it is in zsh
but apparently not bash
, it is more likely to use the shell's environment and do the right thing.)
type
is a POSIX-compliant command which is required to behave as if it were a built-in (that is, it must use the environment of the shell it's invoked from including local aliases and functions), so it usually is a built-in.
It isn't generally found in csh
/tcsh
, although in most modern versions of those which
is a shell builtin and does the right thing; sometimes the built-in is what
instead, and sometimes there's no good way to see the current shell's environment from csh
/tcsh
at all.
A login shell is the first process that executes under your user ID when you log in for an interactive session. The login process tells the shell to behave as a login shell with a convention: passing argument 0, which is normally the name of the shell executable, with a -
character prepended (e.g. -bash
whereas it would normally be bash
. Login shells typically read a file that does things like setting environment variables: /etc/profile
and ~/.profile
for the traditional Bourne shell, ~/.bash_profile
additionally for bash†, /etc/zprofile
and ~/.zprofile
for zsh†, /etc/csh.login
and ~/.login
for csh, etc.
When you log in on a text console, or through SSH, or with su -
, you get an interactive login shell. When you log in in graphical mode (on an X display manager), you don't get a login shell, instead you get a session manager or a window manager.
It's rare to run a non-interactive login shell, but some X settings do that when you log in with a display manager, so as to arrange to read the profile files. Other settings (this depends on the distribution and on the display manager) read /etc/profile
and ~/.profile
explicitly, or don't read them. Another way to get a non-interactive login shell is to log in remotely with a command passed through standard input which is not a terminal, e.g. ssh example.com <my-script-which-is-stored-locally
(as opposed to ssh example.com my-script-which-is-on-the-remote-machine
, which runs a non-interactive, non-login shell).
When you start a shell in a terminal in an existing session (screen, X terminal, Emacs terminal buffer, a shell inside another, etc.), you get an interactive, non-login shell. That shell might read a shell configuration file (~/.bashrc
for bash invoked as bash
, /etc/zshrc
and ~/.zshrc
for zsh, /etc/csh.cshrc
and ~/.cshrc
for csh, the file indicated by the ENV
variable for POSIX/XSI-compliant shells such as dash, ksh, and bash when invoked as sh
, $ENV
if set and ~/.mkshrc
for mksh, etc.).
When a shell runs a script or a command passed on its command line, it's a non-interactive, non-login shell. Such shells run all the time: it's very common that when a program calls another program, it really runs a tiny script in a shell to invoke that other program. Some shells read a startup file in this case (bash runs the file indicated by the BASH_ENV
variable, zsh runs /etc/zshenv
and ~/.zshenv
), but this is risky: the shell can be invoked in all sorts of contexts, and there's hardly anything you can do that might not break something.
† I'm simplifying a little, see the manual for the gory details.
Best Answer
Make csh transfer control to bash when you log in. Put this in your
.login
: