type -a

I just learned about type -a. I knew about type but never knew about the -a flag.

There are several ways to check if a command exists and where it is:

$ command -v ffmpeg
/usr/bin/ffmpeg

$ type ffmpeg
ffmpeg is /usr/bin/ffmpeg

$ which ffmpeg
/usr/bin/ffmpeg

$ whereis ffmpeg
ffmpeg: /usr/bin/ffmpeg /usr/share/ffmpeg /usr/share/man/man1/ffmpeg.1.gz


$ command -v history
history

$ which history
# (empty)

$ type history
history is a shell builtin

$ whereis history
history: /usr/share/man/man3/history.3readline.gz

These are all fine and dandy but often what I want is to know is:

  1. Is this a shell built-in, an alias, or a program (executable file)?
  2. Do I have multiple things with this name available? i.e. if it wasn't first on my $PATH, are there others?

This is where type -a comes into play. If we try with ffmpeg again it doesn't reveal anything interesting:

$ type -a ffmpeg
ffmpeg is /usr/bin/ffmpeg

But what about echo or ls? Are those built-ins? Aliases? Maybe both?

$ type -a ls
ls is aliased to `ls --color=auto'
ls is /bin/ls

$ type -a echo
echo is a shell builtin
echo is /bin/echo

The other confusing thing about all this is that help echo and man echo will give you help for the different versions:

$ help echo
echo: echo [-neE] [arg ...]
    Write arguments to the standard output.

    Display the ARGs, separated by a single space character and followed by a
    newline, on the standard output.

    Options:
      -n        do not append a newline
      -e        enable interpretation of the following backslash escapes
      -E        explicitly suppress interpretation of backslash escapes

    `echo' interprets the following backslash-escaped characters:
      \a        alert (bell)
      \b        backspace
      \c        suppress further output
      \e        escape character
      \E        escape character
      \f        form feed
      \n        new line
      \r        carriage return
      \t        horizontal tab
      \v        vertical tab
      \\        backslash
      \0nnn     the character whose ASCII code is NNN (octal).  NNN can be
                0 to 3 octal digits
      \xHH      the eight-bit character whose value is HH (hexadecimal).  HH
                can be one or two hex digits

    Exit Status:
$ man echo
ECHO(1)                          User Commands                         ECHO(1)

NAME
       echo - display a line of text

SYNOPSIS
       echo [SHORT-OPTION]... [STRING]...
       echo LONG-OPTION

DESCRIPTION
       Echo the STRING(s) to standard output.

       -n     do not output the trailing newline

       -e     enable interpretation of backslash escapes

       -E     disable interpretation of backslash escapes (default)

       --help display this help and exit

       --version
              output version information and exit

       If -e is in effect, the following sequences are recognized:

       \\     backslash

       \a     alert (BEL)

       \b     backspace

       \c     produce no further output

       \e     escape

       \f     form feed

       \n     new line

       \r     carriage return

       \t     horizontal tab

       \v     vertical tab

       \0NNN  byte with octal value NNN (1 to 3 digits)

       \xHH   byte with hexadecimal value HH (1 to 2 digits)

       NOTE: your shell may have its own version of echo, which usually supersedes the version described here.  Please refer to your shell's
       documentation for details about the options it supports.

AUTHOR
 Manual page echo(1) line 1 (press h for help or q to quit)

It turns out help echo is for the bash builtin echo and man echo is for /bin/echo (GNU coreutils).

help is a Bash builtin that documents Bash builtins.

man looks up installed manual pages but not necessarily the command your shell will execute. We can see all the manuals it will load like so:

$ man -aw echo
/usr/share/man/man1/echo.1.gz

man can document either the built-in or program, so it's kind of hard to tell which one its for, but there's a clue at the bottom:

root@home:~# man echo | tail -n1
GNU coreutils 8.28                 January 2018                       ECHO(1)

GNU coreutils are programs, not shell built-ins.

Another way to check (on Debian) is:

$ dpkg -S "$(man -w echo)"
coreutils: /usr/share/man/man1/echo.1.gz

This will tell you which package owns the file.


Credit:

(I have no affiliation with this man, this just came across my Instagram feed and thought it was good enough to expand on and share)

← All posts