$ which ls
/usr/bin/ls
$ type ls
ls is aliased to `ls --color=auto'
$ command -v ls
alias ls='ls --color=auto'
Suddenly I find myself irritated at Debian despite not even using it. Why would they not just include the GNU one? % which ls
ls: aliased to /bin/ls --color=auto
Which makes way more sense. Your "which" is not telling you what will actually be executed when you run the `ls` command there. `command`, on the other hand, is guaranteed to be a built-in, has consistent behavior, and has defined, consistent output, unlike `which`. What `which` outputs will be different depending on shell and what implementation of `which` you actually have installed. NAME
which - shows the full path of (shell) commands.
DESCRIPTION
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 vari‐
able PATH using the same algorithm as bash(1).That description is also doesn't correctly describe the behavior of the command if the shell has any aliases or built-ins of that name. If you have an alias that points to a different command, then `which` is distinctly not printing the executable that would have been executed.
% which which
which: shell built-in command
% command which which
/run/current-system/sw/bin/which
I like to use `which` together with `realpath` to see what exact version of a program I'm using, e.g. (in Fish), [I] ⋊> ~ realpath (command which which)
/nix/store/3w3rvxhlv5dcmdih72da6m613qyav9kw-which-2.21/bin/which
Idk if it's also POSIX, but `command` also typically has an analogue called `builtin` that you can use ensure that you are not looking at an external command, e.g.: [I] ⋊> ~ builtin which which # Fish doesn't have a builtin called `which`
fish: Unknown builtin “which”
[I] ⋊> ~ command command command # and I don't have an external command called `command`
command: command not found
It can also be useful for figuring out which package owns an executable you're running, e.g., on Debian-based systems (also with Fish): > apt show (dpkg -S (realpath (command which php)) | cut -d':' -f1)
Package: php7.4-cli
Version: 7.4.25-1+ubuntu18.04.1+deb.sury.org+1
Priority: optional
Section: php
Source: php7.4
Maintainer: Debian PHP Maintainers <team+pkg-php@tracker.debian.org>
Installed-Size: 4,711 kB
Provides: php-cli, phpapi-20190902
Depends: libedit2 (>= 2.11-20080614-4), libmagic1, mime-support, php7.4-common (= 7.4.25-1+ubuntu18.04.1+deb.sury.org+1), php7.4-json, php7.4-opcache, php7.4-readline, tzdata, ucf, libargon2-1 (>= 0~20171227), libc6 (>= 2.27), libpcre2-8-0 (>= 10.32), libsodium23 (>= 1.0.14), libssl1.1 (>= 1.1.0), libxml2 (>= 2.8.0), zlib1g (>= 1:1.1.4)
Suggests: php-pear
Download-Size: 1,398 kB
APT-Sources: http://ppa.launchpad.net/ondrej/php/ubuntu bionic/main amd64 Packages
Description: command-line interpreter for the PHP scripting language
This package provides the /usr/bin/php7.4 command interpreter, useful for
testing PHP scripts from a shell or performing general shell scripting tasks.
.
The following extensions are built in: Core date filter hash libxml openssl
pcntl pcre Reflection session sodium SPL standard zlib.
.
PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used
open source general-purpose scripting language that is especially suited
for web development and can be embedded into HTML.
N: There is 1 additional record. Please use the '-a' switch to see it
> What `which` outputs will be different depending on shellThis is also true of `command -v`, whose behavior with respect to builtins varies per shell, and is not implemented in some shells.
Fish:
[I] ⋊> ~ fish --version 10:55:42
fish, version 3.3.1
[I] ⋊> ~ command -v command
[I] ⋊> ~ command -v which
/run/current-system/sw/bin/which
tcsh: > tcsh --version
tcsh 6.22.04 (Astron) 2021-04-26 (x86_64-unknown-linux) options wide,nls,dl,al,kan,sm,rh,color,filec
> command -v command
command: Command not found.
> command -v which
command: Command not found.
> builtins | grep command
>
ksh: $ ksh --version
version sh (AT&T Research) 2020.0.0
$ command -v command
'command '
$ command -v which
/run/current-system/sw/bin/which
$
mksh: $ echo $KSH_VERSION
@(#)MIRBSD KSH R59 2020/10/31
$ command -v command
command
$ command -v which
/run/current-system/sw/bin/which
$
pwsh: PS> $PSVersionTable
Name Value
---- -----
PSVersion 7.1.4
PSEdition Core
GitCommitId 7.1.4
OS Linux 5.14.12 #1-NixOS SMP Wed Oct 13 07:42:04 UTC 2021
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
PS> command -v command
PS> command -v which
PS> command which
CommandType Name Version Source
----------- ---- ------- ------
Application which 0.0.0.0 /run/current-system/sw/bin/which
Granted, some of those shells (Fish, tcsh, PowerShell) don't aim for full POSIX compliance, and the most popular shells (bash, dash, zsh) all behave the same way as mksh in the example above. But you can also see that the output given for builtins varies among POSIX shell implementations by comparing the output of the AT&T Korn shell to the MirBSD Korn shell. $ tcsh --version
tcsh 6.21.00 (Astron) 2019-05-08 (x86_64-apple-darwin) options wide,nls,dl,bye,al,kan,sm,rh,color,filec
$ tcsh
% command -v command
command
% command -V command
command is a shell builtin
% builtins | grep command
%If that is the output you've gone out of your way to create an alias in a script, in which case it's reasonable output. It is what will happen when the script runs that command, after all.
$ sh -c 'command -v ls'
/bin/ls