In Debian, a patch has been added to bash, thanks to which the user can write his own function to be performed if the command entered by the user is missing. In Ubuntu, this feature uses the command-not-found tooltip, which significantly slows down the work, while you can find more interesting and useful possibilities for using this mechanism, leaving the search for the package to specialized programs. I will share my experience.
Our unit has a special network for test servers and virtual machines: 192.168.20.0/24, and very often you have to type commands like
ssh user@192.168.20.xx
, and only the last digit is different in the commands. For a limited number of servers, you must specify a different
username
. Less often, you have to go to servers on other subnets (within 192.168.0.0/16); sometimes clients also give us access to their systems so that we can diagnose their problem and solve it on the spot.
As follows from the previous paragraph, very often commands like this are typed:
ssh ordinary_user@192.168.20.xx
ssh special_user@192.168.xx.yy
ssh third_user@ww.xx.yy.zz
There is a natural desire to reduce and optimize this process. When there were few servers, I created a lot of
clever aliases like the following:
alias 123 = 'ssh user@192.168.20.123'
')
However, I soon realized that maintaining a list of fifty alias was not a true unix way, and thought about alternatives. I remembered the experiences of webmasters of the era of web 1.0 on using 404 errors to display a page with the necessary content, thought about how bash intercepts a call from an unknown command and replaces it with a team searching for the right package ... As a result of a cursory examination of the command-not-found package, it was found out that the
command_not_found_handle
function is used. It takes a command entered by the user as an argument, performs some actions and returns 127 if nothing can be done (in this case, bash displays a standard error message), or any other number if something worked out.
The rest turned out to be a matter of technique. A function has been added to
~/.bashrc
:
command_not_found_handle () {
if [[! "$ 1"]]; then
return 127
fi
n = "$ 1"
if echo $ n | perl -ne 'exit (/ ^ ([1-9] | [1-9] \ d | 1 \ d {2} | 2 [0-4] \ d | 25 [0-5]) $ /? 0 :one)' ; then
ip = 192.168.20. $ n
elif echo $ n | perl -ne 'exit (/ ^ ([1-9] | [1-9] \ d | 1 \ d {2} | 2 [0-4] \ d | 25 [0-5]) \ (([ 1-9] | [1-9] \ d | 1 \ d {2} | 2 [0-4] \ d | 25 [0-5]) $ /? 0: 1) '; then
ip = 192.168. $ n
elif echo $ n | perl -ne 'exit (/ ^ ([1-9] | [1-9] \ d | 1 \ d {2} | 2 [0-4] \ d | 25 [0-5]) \ (([ 1-9] | [1-9] \ d | 1 \ d {2} | 2 [0-4] \ d | 25 [0-5]) \. ([1-9] | [1-9] \ d | 1 \ d {2} | 2 [0-4] \ d | 25 [0-5]) \. ([1-9] | [1-9] \ d | 1 \ d {2} | 2 [0-4] \ d | 25 [0-5]) $ /? 0: 1) '; then
ip = $ n
else
return 127
fi
ssh $ ip
}
Any entered number from 1 to 255 is converted to the
ssh 192.168.20.
command
ssh 192.168.20.
. Number; two numbers - in
ssh 192.168..
. number; any entered IP address is converted to
ssh IP-
. In all other cases, the message
"command not found"
is simply displayed.
Since a rather complicated regular expression is used, it was necessary to use perl to process it. There was also a variant with
grep -qP
, but the experimental
-P
option (extended support for perl-regular regular expressions) is not included in grep in all distributions (for example, it is not in Ubuntu 8.04, but already in 8.10).
For all hosts in the 20 network to substitute the common user name ordinary_user, and for selected hosts - special names, in ~ / .ssh / config I added lines (common parameters for all hosts preceded by the
Host *
construct should be at the bottom of the list):
Host 192.168.20.251
User special_user1
Host 192.168.20.252
User special_user2
Host 192.168.20.254
User special_user3
Host *
User ordinary_user
Unfortunately, I was not able to force this function to process the command line parameters too: only the first positional parameter is passed to the command_not_found_handle function, the rest are not available. Therefore, for each non-standard host, you will have to either write the full version of the command with all the parameters, or specify the server settings in ~ / .ssh / config, like the ones above. There are other shortcomings in the implementation, discussed, in particular, on the site
smylers hates software .
However, even with such limitations, new exciting opportunities are opening up. I think that the application proposed by me is not the only one, and this post is not the last one on this topic.
PS bonus for those who read up to this point: a
library of regular expressions perl , where I found a regexp to check the string for IP address compliance.