2021-01-11
How to make Bash fail badly on Ubuntu 16.04 by typo'ing a command name
Here's something I did today, more or less presented in illustrated form, and which I'm glad that I didn't run into before now (since our 16.04 machines don't have long to live):
$ tail -f /var/log/logfile | fgrep uncommon | efgrep -v '(neg1|neg2)' No command 'efgrep' found, did you mean: Command 'vfgrep' from package 'atfs' (universe) Command 'dfgrep' from package 'debian-goodies' (main) Command 'egrep' from package 'grep' (main) Command 'fgrep' from package 'grep' (main) Command 'zfgrep' from package 'zutils' (universe) Command 'zfgrep' from package 'gzip' (main) efgrep: command not found ^C^C^\
Congratulations, your shell is now hung unless both your 'tail
-f
' and your 'fgrep
' produce output frequently (if they do,
fgrep
and then tail
will try to write into a closed pipe and
then exit). If they don't, for example if the log file doesn't see
many updates and most of them don't match the fgrep
string, you
need to kill the tail
to get out from this. This will also happen
in simpler cases where you just have the 'tail -f
' and the typo'd
command.
(When I did this I was in the process of iterating a command line,
and I typo'd my change from fgrep
to egrep
because now I needed
to filter out more than one thing.)
The simple thing to say about this is that it only happens on Ubuntu
16.04, not on 18.04 or 20.04, and it happens because Ubuntu's normal
/etc/bash.bashrc
defines a command_not_found_handle
function
that winds up running a helper program to produce this 'did you mean'
report. The helper program comes from the command-not-found
package,
which is installed because it's Recommended by ubuntu-standard
.
Merely having a command not found handle function doesn't produce this problem even with the 16.04 version of Bash (which is reported as '4.3.48(1)'), because I don't seem to get it if I define the trivial one of:
command_not_found_handle() { printf "%s: command not found\n" "$1" 1>&2; return 127 }
I don't know if the Ubuntu 16.04 problem is something in how the helper program is implemented, something in Bash, or both combining together. As a result, I can't confidently say that this problem is gone in later versions of Bash, as it may just be patched over by a change in the helper program.
(When the 16.04 Bash is hung, the process listing only has the main
Bash shell process, the tail
, and the fgrep
, so it's not an obvious
problem with the helper program where it refuses to exit or something.)
Given the uncertainties around this Ubuntu feature and the general noise
it produces when you typo a command (plus that our users can't install
packages), I'm sort of tempted to remove the command-not-found
package
on some or all of our Ubuntu machines. But I'm grumpy right now.
(Removing the package does make the 16.04 Bash work right. It winds
up running basically my trivial function above, after some if
checks.)