Bash: Handling Command Not Found
After a recent O/S version upgrade (to openSUSE 11.2) I noticed that bash started being a bit more intelligent when I did something stupid: it started giving me a useful error message when I typed the name of a command that wasn't in my PATH but that was in an "sbin" directory. My reaction at the time was "huh, that's nice", but today I decided I needed a bit more information.
As an example of this behavior, if I type ifconfig while not logged in as root I get the get the following:
$ ifconfig
Absolute path to 'ifconfig' is '/sbin/ifconfig', so running it may require superuser privileges (eg. root).
Which is certainly more useful than a "command not found" message.
Turns out that this capability is a standard feature of bash. From bash's man page:
... A full search of the directories in PATH is performed only if the command is not found in the hash table. If the search is unsuccessful, the shell searches for a defined shell function named command_not_found_handle. If that function exists, it is invoked with the original command and the original command's arguments as its arguments, and the function's exit status becomes the exit status of the shell. If that function is not defined, the shell prints an error message and returns an exit status of 127.
I'm not sure if that's a new feature of bash or if it's just something that's recently implemented in openSUSE.
A quick grep in /etc discovered where it was happening. The function itself is in /etc/bash_command_not_found and that function gets included (if it exists) in your bash session via /etc/bash.bashrc.
The function itself is not that complex but there are a couple of useful tidbits that I wanted to point out as a sidebar. The following code determines if the invoking shell was executed from Midnight Commander or is taking input from a pipe:
# do not run when inside Midnight Commander or within a Pipe
if test -n "$MC_SID" -o ! -t 1 ; then
echo $"$1: command not found"
return 127
fi
And the following determines if the invoking shell is a sub-shell:
# do not run when within a subshell
read pid cmd state ppid pgrp session tty_nr tpgid rest < /proc/self/stat
if test $$ -eq $tpgid ; then
echo "$1: command not found"
return 127
fi
End of sidebar.
At the end of the function there's some code that uses /usr/bin/command-not-found (a python script) to lookup commands in installable packages (via zypper), but you need to set an environment variable (COMMAND_NOT_FOUND_AUTO) to activate it, and of course you need to have python installed. To test this try the following:
$ export COMMAND_NOT_FOUND_AUTO=1
$ pascal
pascal: command not found
$ gcj
The program 'gcj' can be found in the following package:
* gcc-java [ path: /usr/bin/gcj, repository: zypp (repo-oss) ]
Try installing with:
sudo zypper install gcc-java
Since this command-not-found functionality is handled by a bash function, you can of course replace the system installed function (if one exists on your system) with one of your own design. All you need is to include it in your .bashrc script. The entire version of openSUSE's script follows:
command_not_found_handle() {
export TEXTDOMAIN=command-not-found
local cmd state rest
local -i pid ppid pgrp session tty_nr tpgid
# do not run when inside Midnight Commander or within a Pipe
if test -n "$MC_SID" -o ! -t 1 ; then
echo $"$1: command not found"
return 127
fi
# do not run when within a subshell
read pid cmd state ppid pgrp session tty_nr tpgid rest < /proc/self/stat
if test $$ -eq $tpgid ; then
echo "$1: command not found"
return 127
fi
# test for /usr/sbin and /sbin
if test -x "/usr/sbin/$1" -o -x "/sbin/$1" ; then
if test -x "/usr/sbin/$1" ; then prefix='/usr' ; else prefix='' ; fi
echo $"Absolute path to '$1' is '$prefix/sbin/$1', so running it may require superuser privileges (eg. root)."
return 127
fi
if test -n "$COMMAND_NOT_FOUND_AUTO" ; then
# call command-not-found directly
test -x /usr/bin/python && test -x /usr/bin/command-not-found && /usr/bin/python /usr/bin/command-not-found "$1" zypp
else
# print only info about command-not-found
echo -e $"If '$1' is not a typo you can use command-not-found to lookup the package that contains it, like this:\n cnf $1"
fi
return 127
}
Mitch Frazier is an Associate Editor for Linux Journal.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- New Products
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Reply to comment | Linux Journal
5 hours 44 min ago - Reply to comment | Linux Journal
6 hours 12 sec ago - Favorite (and easily brute-forced) pw's
7 hours 51 min ago - Have you tried Boxen? It's a
13 hours 43 min ago - seo services in india
18 hours 14 min ago - For KDE install kio-mtp
18 hours 15 min ago - Evernote is much more...
20 hours 15 min ago - Reply to comment | Linux Journal
1 day 5 hours ago - Dynamic DNS
1 day 5 hours ago - Reply to comment | Linux Journal
1 day 6 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?



Comments
command_not_found_handle used for oo-style
Try the oobash! It is an oo-style string library for bash 4. It has support for german umlauts. It is written in bash. Many functions are available: -base64Decode, -base64Encode, -capitalize, -center, -charAt, -concat, -contains, -count, -endsWith, -equals, -equalsIgnoreCase, -reverse, -hashCode, -indexOf, -isAlnum, -isAlpha, -isAscii, -isDigit, -isEmpty, -isHexDigit, -isLowerCase, -isSpace, -isPrintable, -isUpperCase, -isVisible, -lastIndexOf, -length, -matches, -replaceAll, -replaceFirst, -startsWith, -substring, -swapCase, -toLowerCase, -toString, -toUpperCase, -trim, and -zfill.
Look at the contains example
###############################
First call the constructor:
[Desktop]$ String a testXccc
Now use object.method:
[Desktop]$ a.contains tX
true
[Desktop]$ a.contains XtX
false
http://sourceforge.net/projects/oobash/
The command-not-found handler
The command-not-found handler originated from Ubuntu, I think, and was accepted into bash somewhere in v3+, but didn't pass the arguments to the function until bash v4.
Well known feature of packagekit copied from debian
http://blogs.gnome.org/hughsie/2008/12/05/command-not-found/
Why no gravatar support for comments? I don't want a login account. It's another password I have better things to do than remember.
Don't have to remember...
...just get a wallet and store your passwords in an ecrypted file:
apt-cache show revelation
Gabriel Menini
Linux Registered User #207262
Can be seen as a security hole
Sometimes giving ambiguous info about the command is better than showing the full path and permissions in order to execute it.
However, this can be assumed as a security-through-obscurity approach and some people may not like it.
Take ssh login for example. If you don't type the correct username & password you won't get access to the remote box. If you match the user but the password is still wrong, the remote dæmon won't let you know that _only_ the password was incorrect.
I've found some powerful bash shells over there (say Ubuntu and OpenSUSE) that suggests you the package where the 'command not found' can be found, if not installed.
User-friendly: sure! Safe: not so sure....
Gabriel Menini
Linux Registered User #207262
I don't think you're right.
I don't think you're right. This information (what package to get the command) can so simply be found looking for " package" on a search engine on Internet, that it can't be considered as a secret.
So be friendly with million people is definitively more important than assuming a really little security option for some rare cases.
How about Debian squeeze?
So Ubuntu does this - anyone know if there's similar functionality in squeeze (that needs to be enabled) because it doesn't do it for me at the moment?
Another related usefull bash feature
bash has built-in command called shopt, that can do similar things, like auto correction of directory names (on cd command):
shopt -s cdspellYou can read more about shopt here.
--
My blog: http://frishit.wordpress.com
Is this default in other distributions
Sounds like a great feature, good job openSUSE for enabling it by default.
Does anyone know if Fedora or Ubuntu enable similar behavior by default?
Very useful :-)
Ubuntu has for a long time
a couple of responses have described mis-spelling responses, but Ubuntu goes a step further. If you properly spell the command, but the package is not installed, BASH will tell you how to install the package so the command will be available.
Ubuntu does.
Ubuntu does.
ubuntu@karmic:~$ pascal
No command 'pascal' found, did you mean:
Command 'pscal' from package 'xcal' (universe)
pascal: command not found
Ubuntu does...
...and it is REALLY useful as it even copes with mis-spellings:
$ pascalNo command 'pascal' found, did you mean:
Command 'pscal' from package 'xcal' (universe)
pascal: command not found
$ pling
No command 'pling' found, did you mean:
Command 'plink' from package 'putty-tools' (universe)
Command 'ping' from package 'inetutils-ping' (universe)
Command 'ping' from package 'iputils-ping' (main)
pling: command not found
$
so even with my occasionally rubbish typing I get what I need and a good idea of what to install to enable it.
--
Smotsie
Dad.husband.linux-loving-geek.radio-presenter.eco-geek