Git Product home page Git Product logo

what-bash's Introduction

banner image

what-bash

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.

what

Examples

(I ran these on my computer running Ubuntu 18.04.)

Basic usage

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

Show definitions of aliases and functions

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'

Show a problem with a hashed path

If we create a bad hash:

$ hash -p /nonexistent FAKE_COMMAND
$ what FAKE_COMMAND
bash: what: FAKE_COMMAND: File does not exist: /nonexistent

Help and info

$ 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.

symlink-info

Resolve a symlink, recursively and canonically

Example

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

Help

$ 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

Installation

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

In a pinch

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.)

Requirements

  • Bash 4.3+
    • Untested on earlier versions
  • Intended for Debian/Ubuntu, but should work on other Linux distros

Development

If you're editing what.sh, don't forget to source it before running it again, e.g. source ./what.sh; what ...

Roadmap

what

  • Add colour

License

GNU GPLv3

Image credits

what-bash's People

Contributors

wjandrea avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

dev3971

what-bash's Issues

symlink-info doesn't work on orphan symlinks

For example:

$ ln -s /nonexistent orphan
$ symlink-info orphan
symlink-info: No such file: orphan

Cf.

$ ls -l orphan
lrwxrwxrwx 1 wja wja 12 avr 12 16:45 orphan -> /nonexistent

Problem seems to be here:

if ! [[ -e $path ]]; then

since [[ -e orphan ]] fails, which seems strange to me. It does exist even though it's an orphan symlink.

symlink-info gives the wrong output for relative paths

If $link_deref is relative, it assumes $path is relative, which is incorrect.

How I noticed it:

$ cd /usr/src/linux-headers-5.4.0-104-generic/scripts
$ symlink-info extract-vmlinux
extract-vmlinux
    symlink: ../../linux-headers-5.4.0-104/scripts/extract-vmlinux
    canonical path: /usr/src/linux-headers-5.4.0-104/linux-headers-5.4.0-104/scripts/extract-vmlinux

The canonical path is wrong. To get the correct one:

$ readlink -e -- extract-vmlinux 
/usr/src/linux-headers-5.4.0-104/scripts/extract-vmlinux

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.