A detailed explanation of the usage of Whereis in Linux system

Source: Internet
Author: User
Tags assert documentation prev strcmp


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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.