いますぐ実践! Linuxシステム管理

いますぐ実践! Linux システム管理 / Vol.235 / 読者数:2285名

こんばんは、うすだです。

…も、申し訳ございません、またしても1週間遅れの発行となりました。

今年は、年明け早々いろいろありまして、仕事始めの1週間は、 いろいろあった件で吹っ飛んでしまいました。

さらに、20日の週は、後半に風邪を引いたっぽくなり、 これまた完全燃焼できないまま、フワフワしていました。 (まだ過去形じゃないですが。)

今年の初詣では、ひっさびさに大吉を引いたのですが、どう控えめ(?)に考えても、 よい出だしとは思えません。

…いえ、その分、2月以降で持ち直して、 どっかーんといいことがやって来るんだという想いを胸に、 ポジティブにがんばって行きます。

前向きに言い訳したところで、今回もはりきってまいりましょうか!

今回のお題 - Bash の補完機能を活用する

Linuxでは、大抵どのディストリビューションでも、 Bash がデフォルトのシェルになっています。[TAB]キーを押すと、 コマンドやファイルを補完してくれますので、たいへん便利ですよね。

しかし、いつぞやからか、ただただ闇雲に補完するのではなく、 コマンドに合わせて柔軟に補完してくれるようになってきているように思います。

たとえば、「service」コマンドを実行しようとして、 「service a」まで入力したところで補完すると、そこにあるファイルではなく、 サービスの中から「a」で始まる候補を列挙してくださいます。

  $ service a(ここで[TAB]を押す)
  acpi-support  alsa-store    apparmor      auditd        
  acpid         anacron       apport        avahi-daemon  
  alsa-restore  apache2       atd           

たとえばUbuntuの場合ですと、serviceコマンドは 「upstart」パッケージに入っていますが、 Bashの補完のルールも用意してくださっているため、 上記のような補完が可能ということになっています。

というわけで今回は、Bashの補完機能をご紹介します。
既存の設定でも十分便利ですが、 たとえば自作のスクリプトやコマンドに対して設定しておくと、 もっと便利になるのではないかと思います。

Bash のビルトインコマンド - complete

Bashには、「complete」というビルトインコマンドがあります。
オンラインマニュアル(man bash)を参照するとわかりますが、 オプションなどがものすごくたくさんあります。ここでは主なものをご紹介します。

まず、いまの設定内容を確認するには、「-p」オプションを指定して実行します。 標準出力にどばばばっと出力されます。

  $ complete -p
  complete -F _minimal 
  complete -F _filedir_xspec oodraw
  complete -F _filedir_xspec elinks
  ...後略...

コマンドごとに、何らかの設定がされていることがわかります。
特定のコマンドの設定だけ知りたければ、コマンド名も指定します。

  $ complete -p ls
  complete -F _longopt ls

もし設定を消したくなったときは、 「-r」オプションとコマンド名を指定して実行します。 コマンド名を指定しないで実行すると、全設定がまるっと消えますので、 ご注意ください。

  $ complete -r foo
  $ complete -p foo
  bash: complete: hoge: no completion specification

さて、以降では、簡単な補完の設定方法を、延々とご紹介します。
ちなみに、設定するたびに前の設定が上書きされます。

「-d」オプションとコマンド名を指定すると、 そのコマンドの補完対象がディレクトリに限られます。

  $ ls
  dir1/  dir2/  file1  file2
  $ complete -d foo
  $ foo (ここで[TAB]キーを押す)
  dir1   dir2

「-f」オプションの場合は、ファイルかディレクトリに限られます。
(ファイルに限定だと思いますが、ディレクトリをたどれないといけないため、 結果的にどちらも選べるのだと思います。)

  $ complete -f foo
  $ foo (ここで[TAB]キーを押す)
  dir1   dir2   file1   file2

ファイルやディレクトリ以外の補完もできます。 「-A」オプションと種類を指定すると、指定した種類に限定できます。
たとえば、「user」を指定すると、ユーザ名が候補に挙げられます。

  $ complete -A user foo
  $ foo (ここで[TAB]キーを押す)
  bin          mail          nobody        syslog
  daemon       man           root          usu
  ...後略...

他にも、「command」「group」「hostname」「service」「signal」などがあります。 ちなみに、「-A directory」および「-A file」はそれぞれ「-d」および「-f」 を指定したことと同じ意味になります。

  $ complete -A directory foo
  $ complete -p foo
  complete -d foo

「-W」オプションと単語のリストを指定すると、そのリストを候補としてくれます。

  $ complete -W "aaa bbb ccc" foo
  $ foo (ここで[TAB]キーを押す)
  aaa          bbb           ccc

「-X」オプションとパターンを指定すると、パターンにマッチする候補は除外されます。 他のオプションで洗い出された候補を、さらに絞るために使用します。たとえば、 「.png」で終わるファイルを候補から除外したい場合は、以下のように指定します。

  $ complete -f -X '*.png' foo

パターンが複数ある場合は、「@(パターン1|パターン2|...)」という形式で指定します。 たとえば、PNG画像だけでなく、GIFやJPEGなんかの画像も除外したい場合は、 以下のように指定します。

  $ complete -f -X '*.@(png|gif|jpg|jpeg)' foo

ちなみに、パターンの先頭に「!」をつけると否定になります。つまり、 パターンにマッチする候補だけに限定できます。

また、「-o」オプションでは、オプション的な動作を指定できます。
たとえば、「bashdefault」を指定すると、候補がなかったときに、 Bashのデフォルトの補完を試みます。
「dirnames」を指定すると、候補がなかったときに、 ディレクトリを候補に加えます。
「filenames」を指定すると、候補がファイル名であることを前提として補完します。 たとえば、スペースや特殊な文字の前に「\」を入れたり、 ディレクトリの末尾に「/」を加えたりしてくれます。

疲れてきたので応用例を

…きりがないので、説明はこの位にして、簡単な例をいくつか示します。

引数に指定されたホストにアクセスするスクリプト「bar.sh」を作ったとします。 そんなときは、以下のように設定します。

  $ complete -A hostname bar.sh
  $ ./bar.sh (ここで[TAB]キーを押す)
  ::1                  ibook                ubuntu1204
  dnsserv              localhost            vista
  ...後略...

「-A hostname」により、 /etc/hostname から引っ張ってきたホスト名を候補に挙げてくれます。


なにかのサービスを制御するスクリプト「service.sh」を作った場合は、 スクリプトが解釈できるコマンドを「-W」オプションで指定します。

  $ complete -W "start stop status reload restart" service.sh
  $ ./service.sh r(ここで[TAB]キーを押す)
  reload               restart

MP3なファイルを引数に指定して操作するスクリプト「mp3nantoka.sh」を作ったなら、 引数を「-f」オプションでファイルに限定し、 さらに末尾が「.mp3」なものに絞るとよいかと思います。

  $ complete -f -X '!*.mp3' mp3nantoka.sh

ただ、これだと、他のディレクトリにあるファイルを指定できません。
では、マッチしないときにディレクトリを列挙させてみる、 というのではいかがでしょうか。

  $ complete -o dirnames -f -X '!*.mp3' mp3nantoka.sh

ただ、この場合でも、そのディレクトリにMP3ファイルの候補を見つけた時点で、 ディレクトリをたどらなくなりますが…。
(このへんの解決策は、次回にがんばってご紹介する予定です。)


Subversionの管理ディレクトリ「.svn」を候補から外したいとします。
まずは安直に、「-X」オプションで「.svn」を指定してみましょう。

  $ complete -d -X '.svn' oreore.sh

この場合、カレントディレクトリにあるヤツは除外されますが、 他の場所にある場合や、 「./.svn」で指定すると、候補に挙げられてしまいます。
では、このように指定してみると、どうでしょうか。

  $ complete -d -X '@(*/.svn|.svn)' oreore.sh

…これなら、大丈夫そうです。

おわりに

以上、Bash のビルトインコマンド complete の使い方を、 ざざっと簡単にご紹介しました。

ここまで書いておいてなんですが、実は「bash-completion」なるものがあり、 最初に紹介しましたUpstartなんかも、これの設定ファイルを用意してくださっています。

補完のルールを引数ごとに設定したりなど、 いろいろ複雑なことができると踏んでいますので、 次回にご期…いえ、そんな内容かもしれないくらいに思っていただけますと幸いです。

宿題の答え

前回の宿題は、

  SNMPv3でアクセスすると、パスワードがどう見えるか確認しましょう。

でした。

案の定、以前設定したユーザ名とパスワードをすっかり失念してしまい、 あらためて設定して挑みました…というのはこちらの都合ですので置いておきまして、 「-d」オプションをつけて「snmpget」コマンドを実行すると、 UDPパケットのペイロードをダンプしてくれます。

  $ snmpget -d -v 3 -l authNoPriv -u ユーザ -a SHA -A パスワード \
  localhost system.sysDescr.0
  Sending 64 bytes to UDP: [127.0.0.1]:161->[0.0.0.0]
  ...中略...
  Received 116 bytes from UDP: [127.0.0.1]:161->[0.0.0.0]
  ...中略...
  Sending 135 bytes to UDP: [127.0.0.1]:161->[0.0.0.0]
  0000: 30 81 84 02  01 03 30 11  02 04 74 47  11 CC 02 03    0.....0...tG....
  0016: 00 FF E3 04  01 05 02 01  03 04 37 30  35 04 11 80    ..........705...
  0032: 00 1F 88 80  24 B4 15 17  D8 3E CC 50  00 00 00 00    ....$....>.P....
  0048: 02 01 1D 02  02 43 97 04  09 XX XX XX  XX XX XX XX    .....C...XXXXXXX
  0064: XX XX 04 0C  YY YY YY YY  YY YY YY YY  YY YY YY YY    XX..YYYYYYYYYYYY
  0080: 04 00 30 33  04 11 80 00  1F 88 80 24  B4 15 17 D8    ..03.......$....
  0096: 3E CC 50 00  00 00 00 04  00 A0 1C 02  04 62 E0 AE    >.P..........b..
  0112: 42 02 01 00  02 01 00 30  0E 30 0C 06  08 2B 06 01    B......0.0...+..
  0128: 02 01 01 01  00 05 00                                 .......
  Received 214 bytes from UDP: [127.0.0.1]:161->[0.0.0.0]
  0000: 30 81 D3 02  01 03 30 11  02 04 74 47  11 CC 02 03    0.....0...tG....
  0016: 00 FF E3 04  01 01 02 01  03 04 37 30  35 04 11 80    ..........705...
  0032: 00 1F 88 80  24 B4 15 17  D8 3E CC 50  00 00 00 00    ....$....>.P....
  0048: 02 01 1D 02  02 43 97 04  09 XX XX XX  XX XX XX XX    .....C...XXXXXXX
  0064: XX XX 04 0C  YY YY YY YY  YY YY YY YY  YY YY YY YY    XX..YYYYYYYYYYYY
  0080: 04 00 30 81  81 04 11 80  00 1F 88 80  24 B4 15 17    ..0.........$...
  0096: D8 3E CC 50  00 00 00 00  04 00 A2 6A  02 04 62 E0    .>.P.......j..b.
  0112: AE 42 02 01  00 02 01 00  30 5C 30 5A  06 08 2B 06    .B......0\0Z..+.
  0128: 01 02 01 01  01 00 04 4E  4C 69 6E 75  78 20 61 61    .......NLinux aa
  0144: 61 61 61 20  33 2E 35 2E  30 2D 32 32  2D 67 65 6E    aaa 3.5.0-22-gen
  0160: 65 72 69 63  20 23 33 34  2D 55 62 75  6E 74 75 20    eric #34-Ubuntu 
  0176: 53 4D 50 20  54 75 65 20  4A 61 6E 20  38 20 32 31    SMP Tue Jan 8 21
  0192: 3A 34 37 3A  30 30 20 55  54 43 20 32  30 31 33 20    :47:00 UTC 2013 
  0208: 78 38 36 5F  36 34                                    x86_64

  SNMPv2-MIB::sysDescr.0 = STRING: Linux aaaaa 3.5.0-22-generic \
  #34-Ubuntu SMP Tue Jan 8 21:47:00 UTC 2013 x86_64

肝心なところを隠蔽していてなんじゃこりゃな感じですが、 送信した方に生パスワードらしきモノが見当たらないことが(実際に実行すると) わかると思います。
ちなみに、2つ目に送信したパケットの内訳は、以下の通りです。

  0x30(SEQUENCE) - 0x8184(長さ 0x81 = 可変で1バイト, 0x84 = 132)
  |
  +-0x02(INTEGER) - 0x01(長さ) - 0x03(msgVersion - SNMPv3)
  +-0x30(SEQUENCE) - 0x11(長さ)
  | |
  | +-0x02(INTEGER) - 0x04(長さ) - 0x744711CC(msgID)
  | +-0x02(INTEGER) - 0x03(長さ) - 0x00FFE3(msgMaxSize)
  | +-0x04(OCTET STRING) - 0x01(長さ) - 0x05(msgFlags)
  | +-0x02(INTEGER) - 0x01(長さ) - 0x03(msgSecurityModel)
  |
  +-0x04(OCTET STRING) - 0x37(長さ)
  | |
  | +-0x30(SEQUENCE) - 0x35(長さ)
  |   |
  |   +-0x04(OCTET STRING) - 0x11(長さ) - ...(msgAuthoritativeEngineID)
  |   +-0x02(INTEGER) - 0x01(長さ) - 0x1D(msgAuthoritativeEngineBoots)
  |   +-0x02(INTEGER) - 0x02(長さ) - 0x4397(msgAuthoritativeEngineTime)
  |   +-0x04(OCTET STRING) - 0x09(長さ) - 0xXX...(msgUserName)
  |   +-0x04(OCTET STRING) - 0x0C(長さ) - 0xYY...(msgAuthenticationParameters)
  |   +-0x04(OCTET STRING) - 0x00(長さ) - (msgPrivacyParameters)
  +-0x30(SEQUENCE) - 0x33(長さ)
    |
    +-0x04(OCTET STRING) - 0x11(長さ) - ...(contextEngineID)
    +-0x04(OCTET STRING) - 0x00(長さ) - (contextName)
    +-0xA0(GetRequest) - 0x1C(長さ)
      |
      +-0x02(INTEGER) - 0x04(長さ) - 0x62E0AE42(RequestID)
      +-0x02(INTEGER) - 0x01(長さ) - 0x00(ErrorStatus)
      +-0x02(INTEGER) - 0x01(長さ) - 0x00(ErrorIndex)
      +-0x30(SEQUENCE) - 0x0C(長さ)
        |
        +-0x06(OID) - 0x08(長さ) - 0x2B06010201010100(.1.3.6.1.2.1.1.1.0)
        +-0x05(NULL) - 0x00(長さ)

詳細は割愛しますが、authNoPriv で実行しましたので、Authentication ありで Privacy なし、 ということで msgAuthenticationParameters には値があり msgPrivacyParameters には値がないことがわかります。

ちなみに、authPriv で実行すると、Privacy にも値が入ります。
また、その場合、お返事のデータが暗号化されて返ってきます。

  $ snmpget -d -v 3 -l authPriv -u ユーザ -a SHA -A パスワード \
  -x AES -X 暗号化パスワード localhost system.sysDescr.0
  ...中略...
  Received 229 bytes from UDP: [127.0.0.1]:161->[0.0.0.0]
  0000: 30 81 E2 02  01 03 30 11  02 04 44 59  1B 58 02 03    0.....0...DY.X..
  0016: 00 FF E3 04  01 03 02 01  03 04 3F 30  3D 04 11 80    ..........?0=...
  0032: 00 1F 88 80  24 B4 15 17  D8 3E CC 50  00 00 00 00    ....$....>.P....
  0048: 02 01 1D 02  02 42 91 04  09 XX XX XX  XX XX XX XX    .....B...XXXXXXX
  0064: XX XX 04 0C  YY YY YY YY  YY YY YY YY  YY YY YY YY    XX..YYYYYYYYYYYY
  0080: 04 08 ZZ ZZ  ZZ ZZ ZZ ZZ  ZZ ZZ 04 81  88 FC 6F FA    ..ZZZZZZZZ....o.
  0096: 3D 35 2A 6F  AE 27 43 29  75 C6 05 7F  51 0A C6 DA    =5*o.'C)u...Q...
  0112: C3 EF D3 F0  A0 57 40 A4  05 65 E9 0F  38 D7 3C 3A    .....W@..e..8.<:
  0128: AD 47 7E 59  E7 D7 66 9D  FF 3F 0B 7E  6F C6 2D 28    .G~Y..f..?.~o.-(
  0144: 69 23 F7 53  BF 50 A3 0F  FB 68 B3 A3  B5 6C 03 EC    i#.S.P...h...l..
  0160: D1 E8 8E EA  70 CC BE 99  B9 E8 4E 18  8C A0 5D 26    ....p.....N...]&
  0176: 8B 42 66 BB  CC C1 DE 17  17 92 BA 5E  C2 43 9E 2E    .Bf........^.C..
  0192: 8A FC 37 7C  5E D4 10 E4  CB B4 6F AA  DF 54 2A D0    ..7|^.....o..T*.
  0208: 4B A5 0F EB  31 C1 81 52  41 B0 B9 02  72 0B 04 92    K...1..RA...r...
  0224: 0B 22 58 F4  C3                                       ."X..

  SNMPv2-MIB::sysDescr.0 = STRING: Linux bbbbb 3.5.0-22-generic \
  #34-Ubuntu SMP Tue Jan 8 21:47:00 UTC 2013 x86_64

authNoPriv の場合、sysDescr の文字列がそのまんま入っていましたが、 authPriv の場合、少なくともそのママではないことがわかります。

隠蔽されたところを生で見るためにも、実際に試してみてくださいませ。

今回の宿題

今回の宿題は、

  completeにオプションを複数指定した際の動作を確認してみましょう。

です。

まあ、やってみればわかることなのですが、 途中までぜんぜん想定せずにいましたので、意外と需要はあるかもと思い、 宿題にしてみました。

せっかくなので、手を動かしてみてください。

あとがき

まあ、カミングアウトしてしまいますと、「年明け早々いろいろ」というのは、 お葬式、というヤツでした。

ただ、今回は、納棺からお通夜、お葬式、そして初七日まで、 すべて経験することができ、不謹慎ではありますが、 貴重な体験ができたという収穫はありました。

たとえば、納棺では、プロの方が非常に手際よく、 かつゆったりと丁寧に説明をはさみながらコトを進められたため、 こちらもあわてることなく、故人のことを想いながら、 納得かつ満足して行うことができました。

いま、「エクスペリエンス」という言葉をあちこちで耳にしますが、 その理由を意外なところで感じられた、という次第です。

最近、上から降ってくるものをこなすだけの日々が続いているのですが、 相手によかったな〜と思ってもらうことの重要さについて、 もやもやーとではありますが、考える必要があるということも感じました。

 

さて、昨年末から発行の遅延が頻発しており、 おのれのスケジューリング能力の低さを再認識しつつ、 申し訳なく思っている今日この頃です。

ここで、いままでの経緯を反省して、来週も続けて発行します! と高らかに宣言するとかっこよいところなのですが、 どうやら再来週くらいまではごたりそうな気配がしております。

そこで、次回は2月第3週にして、絶対遅れないようにしたいと思います。

…という決断自体が後ろ向きだとは思いますが、みなさまにおかれましては、 なにとぞ前向きにとらえていただけますと、たいへん幸いです。

 

今回も、ここまで読んでいただき、超ありがとうございました。
次回は、2月17日(日) の未明にお会いしましょう!

 

「いますぐ実践! Linux システム管理」の解除は、以下からできます。
http://www.usupi.org/sysad/ (まぐまぐ ID:149633)

バックナンバーは、こちらにほぼ全部そろっています。
http://www.usupi.org/sysad/backno.html

「栗日記」- まだ結果に結びついてませんが、毎日、精一杯描いてます。
http://www.usupi.org/kuri/ (まぐまぐ ID:126454)
http://usupi.seesaa.net/ (栗日記ブログ)
http://usupi.org/k/ (モバイル栗日記)
http://twitter.com/kuriking/ (栗つぶやき)
http://facebook.com/kuriking3 (栗顔本)


[バックナンバーのトップへ] [Linux システム管理のトップへ]

トップ

バックナンバー
    [日付順] [目的別]

プロフィール

▼ リンク

独学Linux
Linuxデスクトップ環境に関する情報が満載です。 メルマガもありますよ。
Server World
CentOS 6をサーバとしたときの設定例が、これでもかというくらいたくさん載っています。 CentOS以外のディストリビューション(Fedora, Ubuntu)も充実しています。
LINUXで自宅サーバーを構築・導入(Fedora9)
Fedora9のインストールの仕方から管理方法まで、詳しく載っています。 SearchManには情報がもりだくさんです。
マロンくん.NET
〜サーバ管理者への道〜
Linuxをサーバとして使用するための、いろいろな設定方法が載っています。 マロンくんもかわいいです。 なんといっても、マロンくんという名前がいいですね!!
日経Linux
今や数少なくなってしまったLinuxの雑誌。ニュースやガイドもあります。
Linux Square − @IT
@ITが提供する、Linux の情報が満載。 載っていない設定方法はないんじゃないでしょうか。
gihyo.jp…技術評論社
Linuxに限らず様々な技術情報が満載のサイト。 SoftwareDesign誌も、 ソフトウェア技術者は必見です。
SourceForge.JP Magazine
Linux に限らず、オープンソース関連の記事が網羅されています。
ITmediaエンタープライズ:Linux Tips 一覧
Tips というより FAQ 集でしょうか。わからないことがあれば覗きましょう。
IBM developerWorks : Linux
開発者向けですが、勉強になりますよ。
Yahoo!ニュース - Linux
Yahoo!のLinuxに関するニュース一覧です。
栗日記
システム管理とかと全然関係ありませんが、毎日栗の絵を描いています。
システム管理につかれちゃったとき、癒されたいときに、ご覧ください。:-)
WEB RANKING - PC関連
ランキングに参加してみました。押してやってください。

▼ 作ってみました

Add to Google

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本