Linux上的which和whereis命令


=Start=

经常用Linux系统的人应该都接触过which和whereis命令,并会用这些命令进行文件查找/定位。但其中的用法和区别一般不会深究,这里我先简单说一下,待之后阅读了which和whereis命令的源码之后再来细说。

####

whereis

locate the binary, source, and manual page files for a command

BUGS

Since whereis uses chdir(2V) to run faster, pathnames given with the -M, -S, or -B must be full; that is, they must begin with a ‘/’.
whereis has a hard-coded path, so may not always find what you’re looking for.

####

which

shows the full path of (shell) commands.

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 variable PATH using the same algorithm as bash(1).

####

$ whereis identify    # whereis命令会在特定目录(但特定目录是哪些?)中查找符合条件的文件
$ whereis -B /usr/local identify    # 在特定目录中查找符合条件的文件(没有用...)
$ whereis -B /usr/local/ImageMagick-6.9.3-10/bin identify    # 没有用...
$ which identify      # which命令会在 $PATH 中查找,找到一个就退出

下面是测试which和whereis命令功能区别的脚本:

#!/bin/bash
# set -x

echo -e "\$PATH = $PATH"
echo -e "[whereis identify]\t$(whereis identify)"
echo -e "[which identify]\t$(which identify)"
echo -e "\n"

export PATH=/usr/local/ImageMagick-6.9.2-10/bin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin/:/usr/local/sbin
echo -e "\$PATH = $PATH"
echo -e "[whereis identify]\t$(whereis identify)"
echo -e "[which identify]\t$(which identify)"
echo -e "\n"

export PATH=/usr/local/ImageMagick-6.9.3-10/bin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin/:/usr/local/sbin
echo -e "\$PATH = $PATH"
echo -e "[whereis identify]\t$(whereis identify)"
echo -e "[which identify]\t$(which identify)"

然后再放一个用Python实现的「which命令」:

#!/usr/bin/env python
# coding=utf-8

# A minimal version of the UNIX which utility, in Python.
# Author: Vasudev Ram - www.dancingbison.com

from __future__ import print_function
import sys
import os
import os.path
import stat

def usage():
    sys.stderr.write("Usage: python which.py name\n")
    sys.stderr.write("or: which.py name\n")

def which(name):
    found = 0
    for path in os.getenv("PATH").split(os.path.pathsep):
        full_path = path + os.sep + name
        if os.path.exists(full_path):
            """
            if os.stat(full_path).st_mode & stat.S_IXUSR:
                found = 1
                print(full_path)
            """
            found = 1
            print(full_path)
    # Return a UNIX-style exit code so it can be checked by calling scripts.
    # Programming shortcut to toggle the value of found: 1 => 0, 0 => 1.
    sys.exit(1 - found)

def main():
    if len(sys.argv) != 2:
        usage()
        sys.exit(1)
    which(sys.argv[1])

if "__main__" == __name__:
    main()
更多参考链接:

linux下which、whereis、locate、find 命令的区别

=END=

,

《 “Linux上的which和whereis命令” 》 有 4 条评论

  1. 只要是可执行文件,which都会进行查找,即便该可执行文件内容为空:
    `
    export PATH=~/bin:$PATH
    mkdir -p ~/bin
    touch ~/bin/hiexec
    which hiexec

    chmod u+x bin/hiexec
    which hiexec
    `

  2. 漏洞预警 | GhostScript 沙箱绕过(命令执行)漏洞
    https://mp.weixin.qq.com/s/f9Lb08m_EqwXmiXEy88Y-Q
    http://seclists.org/oss-sec/2018/q3/142
    https://bugs.chromium.org/p/project-zero/issues/detail?id=1640
    `
    8 月 21 号,Tavis Ormandy 通过公开邮件列表,再次指出 GhostScript 的安全沙箱可以被绕过,通过构造恶意的图片内容,将可以造成命令执行、文件读取、文件删除等漏洞。

    GhostScript 被许多图片处理库所使用,如 ImageMagick、Python PIL 等,默认情况下这些库会根据图片的内容将其分发给不同的处理方法,其中就包括 GhostScript。

    ImageMagick 是一款广泛使用的图像处理软件,有相当多的网站使用它来进行图像处理。它被许多编程语言所支持,包括 Perl,C++,PHP,Python 和 Ruby 等,并被部署在数以百万计的网站,博客,社交媒体平台和流行的内容管理系统(CMS),例如 WordPress 和 Drupal。
    Python PIL 是 Python 语言中处理图片的第三方模块。
    `

  3. 在命令行上使用ghostscript给PDF文件添加水印

    How add watermark to ghostscript with command line? #从这里拿的命令没问题,执行之后可以添加成功
    https://stackoverflow.com/questions/38693217/how-add-watermark-to-ghostscript-with-command-line

    Watermarking a PDF with ghostscript #这里的ps代码片段可能有点问题导致没有添加成功,但参考这里的bash脚本用上面的内容合并更新之后OK了
    https://matthiasl.github.io/output/Watermarking_a_PDF_with_ghostscript.html

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注