How to make Bash fail badly on Ubuntu 16.04 by typo'ing a command name

January 11, 2021

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

Written on 11 January 2021.
« Thinking through why you shouldn't use plaintext passwords in authentication, even inside TLS
What you can and can't build in Go's module mode »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Jan 11 23:36:49 2021
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.