考えを推測し、bashを使用して存在しないコマンドを実行する

Debianにbashでパッチが追加されました。これにより、ユーザーが入力したコマンドがない場合に実行される独自の関数をユーザーが作成できるようになりました。 Ubuntuでは、この機能はcommand-not-foundヒントによって使用されます。これにより、作業が著しく遅くなりますが、このメカニズムを使用するより興味深い便利な可能性を見つけることができます。 私の経験を共有します。



私たちのユニットには、テストサーバーと仮想マシン用の特別なネットワーク192.168.20.0/24があり、 ssh user@192.168.20.xx



ようなコマンドを入力する必要が非常に多く、最後の数字だけがチームで異なります。 限られた数のサーバーには、異なるusername



が必要です。 他のサブネット(192.168.0.0/16内)にあるサーバーにアクセスする必要はあまりありません。 また、お客様が問題を診断してその場で解決できるように、お客様からシステムへのアクセスを許可される場合があります。



前の段落から次のように、フォームのコマンドは非常に頻繁に入力されます。

  ssh ordinary_user@192.168.20.xx
 ssh special_user@192.168.xx.yy
 ssh third_user@ww.xx.yy.zz 




このプロセスを短縮し、最適化することが自然に望まれています。 サーバーが少ないとき、次のような多くのトリッキーなエイリアスを作成しました。

 エイリアス123 = 'ssh user@192.168.20.123' 




しかし、すぐに、50のエイリアスのリストを維持することは真のUNIX方式ではないことに気付き、代替案について考えました。 404エラーを使用して目的のコンテンツを含むページを表示するWeb 1.0時代のウェブマスターの経験を思い出しました。bashが不明なコマンドをインターセプトし、それを正しいパッケージを見つけるコマンドに置き換える方法について考えました... command_not_found_handle



関数が使用されていること。 ユーザーが入力したコマンドを引数として受け取り、何も実行できない場合はアクションを実行し、127を返します(この場合、bashは標準エラーメッセージを表示します)。



残りは技術の問題であることが判明しました。 ~/.bashrc



関数が追加されました:

  command_not_found_handle(){
     [[!  "$ 1"]]; それから
         127を返す
     fi

     n = "$ 1"

    エコー$ n |  perl -ne 'exit(/ ^([1-9] | [1-9] \ d | 1 \ d {2} | 2 [0-4] \ d | 25 [0-5])$ /?0 :1) '; それから
         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) '; それから
         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) '; それから
         ip = $ n
    他に
         127を返す
     fi

     ssh $ ip
 }




1から255までの数字を入力すると、 ssh 192.168.20.



コマンドssh 192.168.20.



変換されssh 192.168.20.



。 2つの番号ssh 192.168..



; 入力されたIPアドレスはssh IP-



IPアドレスになりssh IP-



。 その他の場合はすべて、 "command not found"



というメッセージが単に表示されます。



かなり複雑な正規表現が使用されるため、perlを使用して処理する必要がありました。 grep -qP



バリアントもありましたが、実験オプション-P



(perl正規表現の拡張サポート)はすべてのディストリビューションのgrepに含まれていません(たとえば、Ubuntu 8.04には存在しませんが、8.10にすでに存在します)。



20のネットワーク上のすべてのホストに共通のユーザー名normal_userを、選択したホストに特別な名前を使用するために、〜/ .ssh / configに行を追加しました( Host *



構造の前にあるすべてのホストの一般パラメーターはリストの最後にある必要があります):

 ホスト192.168.20.251
ユーザーspecial_user1

ホスト192.168.20.252
ユーザーspecial_user2

ホスト192.168.20.254
ユーザーspecial_user3

ホスト*
ユーザーordinary_user 




残念ながら、この関数にコマンドラインパラメーターも処理させることはできませんでした。最初の定位置パラメーターのみがcommand_not_found_handle関数に渡され、残りは使用できません。 したがって、非標準ホストごとに、すべてのパラメーターを使用してコマンドのフルバージョンを記述するか、上記のように〜/ .ssh / configでサーバー設定を指定する必要があります。 特に、 smylersが嫌いなソフトウェア Webサイトで議論されている他の実装の欠陥があります。



しかし、そのような制限があっても、刺激的な新しい機会が開かれています。 私が提案したアプリケーションは唯一のものではなく、この投稿はこのトピックの最後ではないと思います。



この時点まで読んだ人のためのPSボーナス: perl正規表現ライブラリ 、ここで、IPアドレスに対して文字列をチェックするための正規表現を見つけました。



All Articles