what
is a Bash function that gets info about a command, like what exactly it is and where. It can help with understanding a command's behaviour and troubleshooting issues. For example, if you run an executable, delete it, then try running it again, Bash may try to run the file that you just deleted (due to pathname hashing), leading to a confusing error message. what
will tell you about that problem.
Along with it is symlink-info
, which details complicated symlinks. what
uses it on symlinked executable files.
(I ran these on my computer running Ubuntu 18.04.)
Show basic info about a variety of commands:
$ what if type find what
if
keyword
type
builtin
find
file
path: /usr/bin/find
file type: ELF 64-bit LSB shared object
what
function
source: /home/wja/.local/lib/bash/what.sh:348
export: no
A bit more complex:
$ what awk sh ls
awk
file
path: /usr/bin/awk
symlink: /etc/alternatives/awk
symlink: /usr/bin/mawk
file type: ELF 64-bit LSB shared object
sh
file
path: /bin/sh
symlink: dash
canonical path: /bin/dash
file type: ELF 64-bit LSB shared object
ls
alias
possible source: /home/wja/.bash_aliases
file
path: /bin/ls
file type: ELF 64-bit LSB shared object
Use what -d
:
$ function foo { bar; }
$ what -d foo ll
foo
function
source: main:2
export: no
definition:
foo ()
{
bar
}
ll
alias
possible source: /home/wja/.bash_aliases:25
definition: alias ll='ls -alF' # all, long, classified
definition: alias ll='ls -alF'
Note that the source of a function can be traced, but not an alias. what
basically guesses at alias sources. Specifically, it tries to find the alias name in the most common files, using a regex. It doesn't look at the definition, for example:
$ alias ll='do_something_else'
$ what -d ll
ll
alias
possible source: /home/wja/.bash_aliases:25
definition: alias ll='ls -alF' # all, long, classified
definition: alias ll='do_something_else'
If we create a bad hash:
$ hash -p /nonexistent FAKE_COMMAND
$ what FAKE_COMMAND
bash: what: FAKE_COMMAND: File does not exist: /nonexistent
$ what -h
Usage: what [-hiv] [-dnt] [name ...]
Give information about Bash command names, like a more thorough "type".
Arguments:
NAME Command name to give information about.
If none are given, input is taken from stdin.
Options:
-d Print definitions for aliases and functions.
-h Print this help message and exit.
-i Print the info message and exit.
-n Provide more info if a command is not found.
Uses "/usr/lib/command-not-found" (available on Debian/Ubuntu)
-t Print only types, similar to "type -at".
-v Print the version and exit.
Exit Status:
4 - Missing dependency ("symlink-info" or optionally the "-n" handler)
3 - Invalid options
1 - At least one NAME is not found, or any other error
0 - otherwise
$ what -i
Info provided per type (types ordered by precedence):
alias
- possible source file(s) and line number(s)
- (with option "-d": definition in file)
- (with option "-d": current definition)
keyword
function
- source file and line number
- marked for export (yes/no)
- (with option "-d": definition)
builtin
hashed file (though not a type per se)
- (if hashed file does not exist: warning)
- path
file(s)
- path
- (if symlink: details from "symlink-info")
- file type
Always iterates over multiple types/instances, e.g:
- echo: builtin and file
- zsh: two files on Debian
For example:
"what if type ls what zsh sh /"
- Covers keyword, builtin, alias/file, function, multiple
files/absolute symlinks, relative symlink (on Debian/Ubuntu),
and non-command.
Known issues:
- Bash may have different output between "type COMMAND" and
"type -a COMMAND" if COMMAND is a file but is not executable.
That includes:
- If the user doesn't have execute permissions to the file
- If the file is a directory
- If the file does not exist, as a hashed path
Some of this behaviour depends on the version of Bash.
Since "what" relies on the output of "type" to make sense of the
environment, it will print an error or warning if affected.
Resolve a symlink, recursively and canonically
Borrowing from the above what
example:
$ symlink-info /usr/bin/awk /bin/sh
/usr/bin/awk
symlink: /etc/alternatives/awk
symlink: /usr/bin/mawk
/bin/sh
symlink: dash
canonical path: /bin/dash
$ symlink-info -h
Usage: symlink-info [-hv] [file ...]
Resolve a symlink, recursively and canonically.
Arguments:
FILE Filename of symlink to resolve.
Options:
-h Print this help message and exit.
-v Print the version and exit.
Info provided per symlink:
- target, recursively
- (if relative: canonical path)
- (if broken: warning)
Exit Status:
3 - Invalid options
1 - At least one FILE is not found, or any other error
0 - otherwise
Put symlink-info.sh
in your PATH
as symlink-info
. Source what.sh
to get the function what
.
what.sh
can also be run directly, but it's not recommended since it won't have access to the active shell environment, e.g. aliases.
Everything else is your choice. For example, you might want to source what.sh
from your bashrc so that you always have what
available.
For command name completion:
complete -c what
cd
into the src
directory, then:
hash -p "$PWD/symlink-info.sh" symlink-info &&
source "$PWD/what.sh" &&
complete -c what
(Using $PWD
with what.sh
so that there's a record of where what
came from.)
- Bash 4.3+
- Untested on earlier versions
- Intended for Debian/Ubuntu, but should work on other Linux distros
If you're editing what.sh
, don't forget to source it before running it again, e.g. source ./what.sh; what ...
what
- Add colour
GNU GPLv3
- Theme: Solarized Dark by Ethan Schoonover
- Font: Ubuntu Mono