Structure of error messages in bash

Bash error messages sometimes have a -bash: or bash: prefix, sometimes none.

Consider these error messages from Ubuntu 14.04.5 Trusty Tahr with bash 4.3.11(1)

$ type encabulator
-bash: type: encabulator: not found

$ encabulator
encabulator: command not found

$ bash -c encabulator
bash: encabulator: command not found

In another question, someone reports seeing a message

-bash: fetch: command not found.

Which doesn't match the pattern expected when "fetch" is simply a program that has not been installed.


After comments below, I tried using bash 3.2.25(1) on Centos 5.7 - which behaves slightly differently

$ type encabulator
-bash: type: encabulator: not found

$ encabulator
-bash: encabulator: command not found

$ bash -c encabulator
bash: encabulator: command not found

So I guess the message from the other question means exactly what I first thought, before my test with bash 4.3.11 confused me.

It still leaves open the question of whether the bash maintainers intended to apply some consistent system to the structure of these text messages?


When exactly does bash prefix error messages with -bash: and when with bash: (what does the leading hyphen indicate?)

I couldn't find answers using a simple search in man bash but maybe there's a section that provides an explanation?


When exactly does bash prefix error messages with -bash: and when with bash:

The prefix, if printed, is usually the name with which bash was started, aka argv[0] (usually available in $0).

$ bash -c 'type foo; echo $0'
bash: line 0: type: foo: not found
bash
$ ARGV0=bar bash -c 'type foo; echo $0'
bar: line 0: type: foo: not found
bar
$ ARGV0='¯\(°_o)/¯' bash -c 'type foo; echo $0'
¯\(°_o)/¯: line 0: type: foo: not found
¯\(°_o)/¯

(This uses zsh's special ARGV0 variable to set argv[0] of a command to whatever we want.)

For starting bash as a login shell, whatever starts bash may prefix argv[0] with -, or use the -l option. See Invoking Bash:

A login shell is one whose first character of argument zero is ‘-’, or one invoked with the --login option.

So, for example,

$ ARGV0=-bash bash -c 'echo -n $0:;shopt -q login_shell && echo login || echo not login'
-bash:login
$ bash -c 'echo -n $0:;shopt -q login_shell && echo login || echo not login'
bash:not login

SSH, sudo (with -i), the TTY login command, etc. usually use the leading - method to start a login shell. So, if you logged in via any of these, you're likely to see -bash (or -zsh, or -tcsh, or whatever you login shell is with - in front of it). If you started bash via a terminal emulator, those usually run non-login shells and you'd see bash.


what does the leading hyphen indicate?

That it's probably a login shell, which may be an useful point in debugging. In particular, PATH is often set from files sourced by login shells (/etc/profile, ~/.profile, ~/.bash_profile, etc. - see Bash Startup Files for more). For a command-not-found error, this would be particularly important, since PATH is how commands are found. It gives you useful information as to which files should be checked for modifying PATH.


When exactly does bash prefix error messages with -bash: and when with bash:

It is arbitrary.

what does the leading hyphen indicate?

Nothing useful. See muru's answer which points out that the hyphen indicates that the error message is being reported by a login shell.


Bash Manual

The GNU manual for Bash mentions a shell option

gnu_errfmt

    If set, shell error messages are written in the standard GNU error message format.

I tried setting it, the results in the question were unchanged.

GNU Coding Standards

The GNU Coding Standards seem mainly concerned with error messages from compilers (i.e. gcc?) however, section 4.4 says

4.4 Formatting Error Messages

...

... like this:

    program: message

when there is no relevant source file.  

GNU libc

GNU's libc manual gives this example for producing error messages.

fprintf (stderr, "%s: Couldn't open file %s; %s\n",
               program_invocation_short_name, name, strerror (errno));
      exit (EXIT_FAILURE);

From the lack of detail in the above documentation and from the variation seen in the question, I deduce that there is no specific meaning intended by the presence or absence of the bash: prefix.