Command function:
Find binary Files location
Find the location of the software's configuration file
Find source code file location
View the man manual location
Grammar
The basic syntax is as follows:
Whereis command
OR
Whereis Program
OR
Whereis [Options] Program
OR
Whereis-bms directory-f Command
Whereis Use examples:
Find the location of the date command's executable file, source code, and Man manual, enter:
$ Whereis Date
The output is shown below:
Whereis-command-demo.gif
Animated GIF 01:whereis command running on my Debian based server
How do I search only the location of a binary file?
Use the-B parameter:
$ whereis-b Date
How do I search only the location of the man Handbook?
Use the-m parameter:
$ whereis-m Date
How do I search only the location of source code files?
Use the-s parameter:
$ whereis-s Date
Problem: The Whereis-u parameter is problematic, according to man Whereis, and-U is searching for files that have no binaries or source code files or man manuals. But the actual test found that there was no relationship with the wool.
An example in the Man Handbook:
A file is said to being unusual if it does not have one entry of each requested type. Thus The following example, asks for those files in the current directory which have no documentation (meaning that there is no man document in the present directory Pieces):
$ whereis-m-U *
We first Cd/bin and then execute the above command, and we find that whereis-m-u * and where-m * results are identical. The function of-u does not show up at all. And it's completely inconsistent with the man document description, because the files in the/bin directory have a man document, according to the man document, the result should be empty, but the result is not empty.
How do I limit the search path?
Use the following parameters to limit the corresponding search path:
-b/path/to/dir: Restricts the search of binaries to the specified directory.
-m/path/to/dir: Restricts search of man manual files in specified directories.
-s/path/to/dir: Restricts the search of binaries to the specified directory.
When you use any of the parameters---B,-M,-s, you must add the-f argument, and then specify the file name to search for.
Examples are as follows: only the ls and gcc are searched under the/bin directory:
$ whereis-b/bin-f ls gcc
The results are as follows:
1
2
LS:/bin/ls/usr/share/man/man1/ls.1.gz
Gcc:
As you can see, GCC searches for binaries in the/bin directory without results, stating that GCC binaries are not in the/bin directory.
Question: However, I found that although there is no GCC binaries in the/bin directory, there is still output using the commands above, rather than as I translated this article.
Example 2: This is also the example in The Man Handbook, tested, where the-u parameter is not in accordance with the man's manual.
Find files in all/usr/bin directories whose man documents are not/usr/man/man1/and whose source code files are not/usr/src/, enter:
# Cd/usr/bin
# whereis-u-ms-m/usr/man/man1-s/usr/src-f *
Test:
#cd/bin
#whereis-u-m-m/root-f *
According to the man manual, this line of command functions: Find all/bin files whose man documents are not/root. So there should be a result output, because the/root directory does not have any files on the man manual. Yes, surprised to find that the result is actually empty.
Whereis command Options
From the Whereis (1) Command Mans page:
Option meaning
-F Define Search scope.
-B Search only binaries.
-B Define binaries lookup path.
-M Search only manual paths.
-M Define Mans lookup path.
-S Search only sources path.
-S Define sources lookup path.
-U Search from unusual enties.
-V Output version information and exit. Invalid, man document without this parameter
-H Display this help and exit. Invalid, man document has no this parameter
ALSO
Whereis (1) Linux/unix Command man page
Category List of Unix and Linux commands
File Management Cat
Network Utilities Dig Host IP
Processes Management BG Chroot disown FG jobs kill Killall pwdx Time Pidof Pstree
Searching Whereis which
User information groups ID last Lastcomm logname users w who whoami lid members
About the Whereis-u parameter function, because do not know the Whereis version, not to find the corresponding version of the Whereis source code, I found a new version of the Whereis C source code, the obvious discovery, Whereis use hard-coded paths.
Whereis code address on git: https://github.com/karelzak/util-linux/blob/master/misc-utils/whereis.c#L96
The code is as follows:
/*-
* Copyright (c) 1980 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* Modification, are permitted provided that following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* Notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* Notice, this list of conditions and the following disclaimer in the
* documentation and/or materials provided with the distribution.
* 3. All advertising materials mentioning features or with this software
* Must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* May is used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This SOFTWARE was provided by the regents and CONTRIBUTORS ' as is ' and
* Any EXPRESS OR implied warranties, including, BUT not LIMITED to, the
* Implied warranties of merchantability and FITNESS for A particular purpose
* ARE disclaimed. In NO EVENT SHALL the Regents OR CONTRIBUTORS to be liable
* For any DIRECT, INDIRECT, incidental, SPECIAL, exemplary, OR consequential
* Damages (including, BUT not LIMITED to, procurement of substitute goods
* or SERVICES; LOSS of Use, DATA, OR profits; OR BUSINESS Interruption)
* HOWEVER caused and on any theory of liability, WHETHER in CONTRACT, STRICT
* Liability, or TORT (including negligence or otherwise) arising in any WAY
* Out of the "use of" this SOFTWARE, even IF advised of the possibility of
* SUCH DAMAGE.
*
* 1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>
*-Added Native Language Support
* 2011-08-12 Davidlohr Bueso <dave@gnu.org>
*-Added $PATH lookup
*
* Copyright (C) 2013 Karel Zak <kzak@redhat.com>
* 2013 Sami Kerola <kerolasa@iki.fi>
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "xalloc.h"
#include "Nls.h"
#include "c.h"
#include "closestream.h"
#include "canonicalize.h"
#include "Debug.h"
Ul_debug_define_mask (Whereis);
Ul_debug_define_masknames (Whereis) = Ul_debug_empty_masknames;
#define WHEREIS_DEBUG_INIT (1 << 1)
#define WHEREIS_DEBUG_PATH (1 << 2)
#define WHEREIS_DEBUG_ENV (1 << 3)
#define WHEREIS_DEBUG_ARGV (1 << 4)
#define WHEREIS_DEBUG_SEARCH (1 << 5)
#define WHEREIS_DEBUG_STATIC (1 << 6)
#define WHEREIS_DEBUG_LIST (1 << 7)
#define Whereis_debug_all 0xFFFF
#define DBG (M, x) __ul_dbg (Whereis, Whereis_debug_, M, x)
#define ON_DBG (M, x) __ul_dbg_call (Whereis, Whereis_debug_, M, x)
static char Uflag = 0;
/* Supported Types * *
enum {
Bin_dir = (1 << 1),
Man_dir = (1 << 2),
Src_dir = (1 << 3),
All_dirs = Bin_dir | Man_dir | Src_dir
};
* Directories * *
struct Wh_dirlist {
int type;
dev_t St_dev;
ino_t St_ino;
Char *path;
struct Wh_dirlist *next;
};
static const char *bindirs[] = {
"/usr/bin",
"/usr/sbin",
"/usr/lib",
"/usr/lib64",
"/bin",
"/sbin",
"/etc",
"/usr/etc",
"/lib",
"/lib64",
"/usr/games",
"/usr/games/bin",
"/usr/games/lib",
"/usr/emacs/etc",
"/usr/lib/emacs/*/etc",
"/usr/tex/bin",
"/usr/tex/bin",
"/usr/interviews/bin/linux",
"/usr/x11r6/bin",
"/usr/x386/bin",
"/usr/bin/x11",
"/usr/x11/bin",
"/usr/x11r5/bin",
"/usr/local/bin",
"/usr/local/sbin",
"/usr/local/etc",
"/usr/local/lib",
"/usr/local/games",
"/usr/local/games/bin",
"/usr/local/emacs/etc",
"/usr/local/tex/bin",
"/usr/local/tex/bin",
"/usr/local/bin/x11",
"/usr/contrib",
"/usr/hosts",
"/usr/include",
"/usr/g++-include",
"/USR/UCB",
"/usr/old",
"/usr/new",
"/usr/local",
"/usr/libexec",
"/usr/share",
"/opt/*/bin",
Null
};
static const char *mandirs[] = {
"/usr/man/*",
"/usr/share/man/*",
"/usr/x386/man/*",
"/usr/x11/man/*",
"/usr/tex/man/*",
"/usr/interviews/man/mann",
"/usr/share/info",
Null
};
static const char *srcdirs[] = {
"/usr/src/*",
"/usr/src/lib/libc/*",
"/usr/src/lib/libc/net/*",
"/usr/src/ucb/pascal",
"/usr/src/ucb/pascal/utilities",
"/usr/src/undoc",
Null
};
static void Whereis_init_debug (void)
{
__ul_init_debug (Whereis, whereis_debug_, 0, Whereis_debug);
}
static const char *whereis_type_to_name (int type)
{
Switch (type) {
Case Bin_dir:return "BIN";
Case Man_dir:return "Mans";
Case Src_dir:return "SRC";
Default:return "???";
}
}
static void __attribute__ ((__noreturn__)) usage (FILE *out)
{
Fputs (Usage_header, out);
fprintf (Out, _ ("%s [options] <file>\n"), program_invocation_short_name);
Fputs (Usage_separator, out);
Fputs (_ ("Locate the binary, source, and Manual-page files for a command.\n");
Fputs (usage_options, out);
Fputs (_ ("B Search only for binaries\n"), out);
Fputs (_ ("b <dirs> define binaries lookup path\n"), out);
Fputs (_ ("M search only for manuals and infos\n"), out);
Fputs (_ ("M <dirs> define man and Info lookup path\n");
Fputs (_ ("s search only for sources\n"), out);
Fputs (_ ("s <dirs> define sources lookup path\n"), out);
Fputs (_ ("F Terminate <dirs> argument list\n"), out);
Fputs (_ ("-U Search for Unusual entries\n"), out);
Fputs (_ ("L Output effective lookup paths\n"), out);
fprintf (Out, Usage_man_tail ("Whereis (1)"));
Exit = = stderr? exit_failure:exit_success);
}
static void Dirlist_add_dir (struct wh_dirlist **ls0, int type, const char *dir)
{
struct STAT st;
struct Wh_dirlist *prev = NULL, *ls = *ls0;
if (Access (dir, R_OK)!= 0)
Return
if (Stat (dir, &st)!= 0 | |! S_isdir (St.st_mode))
Return
while (LS) {
if (Ls->st_ino = St.st_ino &&
Ls->st_dev = St.st_dev &&
Ls->type = = Type) {
DBG (list, ul_debugobj (*ls0, "ignore (already in LIST):%s", dir));
Return
}
prev = ls;
ls = ls->next;
}
ls = xcalloc (1, sizeof (*LS));
Ls->st_ino = St.st_ino;
Ls->st_dev = St.st_dev;
Ls->type = type;
Ls->path = Canonicalize_path (dir);
if (!*LS0)
*LS0 = ls; /* The The list * *
else {
ASSERT (prev);
Prev->next = ls; /* Add to the ' End of the ' list * *
}
DBG (LIST, Ul_debugobj (*ls0, "Add dir:%s", Ls->path));
Return
}
/* Special case for ' * ' in the paths * *
static void Dirlist_add_subdir (struct wh_dirlist **ls, int type, const char *dir)
{
Char Buf[path_max], *d;
DIR *dirp;
struct Dirent *DP;
strncpy (buf, dir, Path_max);
Buf[path_max-1] = ' the ';
D = STRCHR (buf, ' * ');
if (!d)
Return
*d = 0;
DIRP = Opendir (BUF);
if (!DIRP)
Return
DBG (LIST, Ul_debugobj (*ls, "Scanning subdir:%s", dir));
while (DP = Readdir (DIRP))!= NULL) {
if (!strcmp (Dp->d_name, ".") | |!strcmp (dp->d_name, "..."))
Continue
snprintf (d, Path_max-(D-BUF), "%s", dp->d_name);
/* A DIR definition can have a star in middle of path * *
strcat (buf, Strchr (dir, ' * ') + 1);
Dirlist_add_dir (LS, type, buf);
}
Closedir (DIRP);
Return
}
static void construct_dirlist_from_env (const char *env,
struct Wh_dirlist **ls,
int type)
{
Char *key = NULL, *tok = NULL, *PATHCP, *path = getenv (env);
if (!path)
Return
PATHCP = xstrdup (path);
DBG (ENV, Ul_debugobj (*ls, "construct%s dirlist from:%s")
Whereis_type_to_name (type), path));
for (tok = Strtok_r (Pathcp, ":", &key); Tok
Tok = Strtok_r (NULL, ":", &key))
Dirlist_add_dir (LS, type, tok);
Free (PATHCP);
Return
}
static void construct_dirlist_from_argv (struct wh_dirlist **ls,
int *idx,
int argc,
Char *argv[],
int type)
{
int i;
DBG (ARGV, Ul_debugobj (*ls, "construct%s dirlist from argv[%d ...]",
Whereis_type_to_name (type), *IDX));
for (i = *idx i < argc; i++) {
if (*argv[i] = = '-')/* End of the list * *
Break
DBG (ARGV, Ul_debugobj (*ls, "using argv[%d]:%s", *idx, Argv[*idx]);
Dirlist_add_dir (LS, type, argv[i]);
*idx = i;
}
Return
}
static void Construct_dirlist (struct wh_dirlist **ls,
int type,
const char **paths)
{
size_t i;
DBG (STATIC, Ul_debugobj (*ls, "construct%s dirlist from STATIC array",
Whereis_type_to_name (type)));
for (i = 0; paths[i]; i++) {
if (!STRCHR (paths[i], ' * '))
Dirlist_add_dir (LS, type, paths[i]);
Else
Dirlist_add_subdir (LS, type, paths[i]);
}
Return
}
static void Free_dirlist (struct wh_dirlist **ls0, int type)
{
struct Wh_dirlist *prev = NULL, *next, *ls = *ls0;
*ls0 = NULL;
DBG (LIST, Ul_debugobj (*ls0, "free Dirlist"));
while (LS) {
if (Ls->type & type) {
Next = ls->next;
DBG (LIST, Ul_debugobj (*ls0, "Free:%s", Ls->path));
Free (Ls->path);
Free (LS);
ls = next;
if (prev)
Prev->next = ls;
} else {
if (!prev)
*LS0 = ls; /* The unremoved/*
prev = ls;
ls = ls->next;
}
}
Return
}
static int filename_equal (const char *CP, const char *DP)
{
int i = strlen (DP);
DBG (SEARCH, Ul_debug ("Compare '%s ' and '%s '", CP, DP));
if (dp[0] = = ' s ' && dp[1] = = '. ' && filename_equal (CP, DP + 2))
return 1;
if (!STRCMP (DP + i-2, ".) Z "))
I-= 2;
else if (!STRCMP (DP + i-3, ". gz"))
I-= 3;
else if (!STRCMP (DP + i-3, ". XZ"))
I-= 3;
else if (!STRCMP (DP + i-4, ". bz2"))
I-= 4;
while (*CP && *dp && *CP = = *DP)
cp++, dp++, i--;
if (*CP = = 0 && *dp = 0)
return 1;
while (IsDigit (*DP))
dp++;
if (*CP = = 0 && *dp++ = = '. ') {
I.;
while (i > 0 && *dp)
if (i, *dp++ = = '. ')
return (*dp++ = = ' C ' && *dp++ = 0);
return 1;
}
return 0;
}
static void Findin (const char *dir, const char *pattern, int *count, char **wait)
{
DIR *dirp;
struct Dirent *DP;
Dirp = Opendir (dir);
if (dirp = NULL)
Return
DBG (SEARCH, Ul_debug ("Find '%s ' in '%s '", Pattern, dir));
while (DP = Readdir (DIRP))!= NULL) {
if (!filename_equal (pattern, dp->d_name))
Continue
if (uflag && *count = 0)
xasprintf (Wait, "%s/%s", dir, Dp->d_name);
else if (uflag && *count = 1 && *wait) {
printf ("%s:%s%s/%s", Pattern, *wait, dir, dp->d_name);
Free (*wait);
*wait = NULL;
} else
printf ("%s/%s", dir, Dp->d_name);
+ + (*count);
}
Closedir (DIRP);
Return
}
static void lookup (const char *pattern, struct wh_dirlist *ls, int want)
{
Char Patbuf[path_max];
int count = 0;
Char *wait = NULL, *p;
/* canonicalize pattern-Remove path suffix etc. * *
p = strrchr (pattern, '/');
p = p? P + 1: (char *) pattern;
strncpy (Patbuf, p, Path_max);
Patbuf[path_max-1] = ' the ';
DBG (SEARCH, Ul_debug ("Lookup dirs for '%s '), want:%s%s%s",
Patbuf, pattern,
Want & Bin_dir? "Bin": "",
Want & Man_dir? "Min": "",
Want & Src_dir? "src": ""));
p = strrchr (Patbuf, '. ');
if (p)
*p = ' n ';
if (!uflag)
/* If-u not specified then we always print the pattern * *
printf ("%s:", patbuf);
for (; ls; ls = ls->next) {
if ((Ls->type & Want) && Ls->path)
Findin (Ls->path, Patbuf, &count, &wait);
}
Free (wait);
if (!uflag | | (Uflag && count > 1))
Putchar (' \ n ');
Return
}
static void List_dirlist (struct wh_dirlist *ls)
{
while (LS) {
if (Ls->path) {
Switch (ls->type) {
Case BIN_DIR:
printf ("Bin:");
Break
Case MAN_DIR:
printf ("Man:");
Break
Case SRC_DIR:
printf ("src:");
Break
Default
Abort ();
}
printf ("%s\n", Ls->path);
}
ls = ls->next;
}
}
int main (int argc, char **argv)
{
struct Wh_dirlist *ls = NULL;
int want = All_dirs;
int i, want_resetable = 0;
SetLocale (Lc_all, "");
Bindtextdomain (PACKAGE, Localedir);
Textdomain (PACKAGE);
Atexit (close_stdout);
if (argc = 1)
Usage (stderr);
Whereis_init_debug ();
Construct_dirlist (&ls, Bin_dir, bindirs);
Construct_dirlist_from_env ("PATH", &ls, Bin_dir);
Construct_dirlist (&ls, Man_dir, mandirs);
Construct_dirlist_from_env ("Manpath", &ls, Man_dir);
Construct_dirlist (&ls, Src_dir, srcdirs);
for (i = 1; i < argc; i++) {
const char *arg = Argv[i];
int arg_i = i;
DBG (ARGV, Ul_debug ("argv[%d]:%s", I, Arg));
if (*arg!= '-') {
Lookup (ARG, LS, want);
/*
* The lookup mask ("want") is cumulative and it ' s
* Resetable only when it has been already used.
*
* Whereis-b-M foo: ' foo ' mask=bin| Mans
* whereis-b foo bar: ' foo ' and ' Bar ' mask=bin| Mans
* Whereis-b foo-m bar: ' foo ' mask=bin; ' Bar ' Mask=man
*/
want_resetable = 1;
Continue
}
for (++arg arg && *arg; arg++) {
DBG (ARGV, Ul_debug ("Arg:%s", Arg));
Switch (*ARG) {
Case ' F ':
Break
Case ' U ':
Uflag = 1;
Break
Case ' B ':
if (* (ARG + 1))
Usage (stderr);
i++;
Free_dirlist (&ls, Bin_dir);
CONSTRUCT_DIRLIST_FROM_ARGV (
&ls, &i, argc, argv, Bin_dir);
Break
Case ' M ':
if (* (ARG + 1))
Usage (stderr);
i++;
Free_dirlist (&ls, Man_dir);
CONSTRUCT_DIRLIST_FROM_ARGV (
&ls, &i, argc, argv, Man_dir);
Break
Case ' S ':
if (* (ARG + 1))
Usage (stderr);
i++;
Free_dirlist (&ls, Src_dir);
CONSTRUCT_DIRLIST_FROM_ARGV (
&ls, &i, argc, argv, Src_dir);
Break
Case ' B ':
if (want_resetable) {
want = All_dirs;
want_resetable = 0;
}
want = want = = All_dirs? Bin_dir:want | Bin_dir;
Break
Case ' m ':
if (want_resetable) {
want = All_dirs;
want_resetable = 0;
}
want = want = = All_dirs? Man_dir:want | Man_dir;
Break
Case ' s ':
if (want_resetable) {
want = All_dirs;
want_resetable = 0;
}
want = want = = All_dirs? Src_dir:want | Src_dir;
Break
Case ' l ':
List_dirlist (LS);
Break
Case ' V ':
printf (util_linux_version);
return exit_success;
Case ' H ':
Usage (stdout);
Default
Usage (stderr);
}
if (Arg_i < i)/* moved to the next argv[] Item * *
Break
}
}
Free_dirlist (&ls, all_dirs);
return exit_success;
}
Rely on, even code comments have errors, lazy toss, brother still have something to do. Anyway-u parameters are actually rarely used, and interested can look at this code.