いますぐ実践! 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」というビルトインコマンドがあります。 まず、いまの設定内容を確認するには、「-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」オプションと種類を指定すると、指定した種類に限定できます。 $ 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」オプションでは、オプション的な動作を指定できます。 疲れてきたので応用例を…きりがないので、説明はこの位にして、簡単な例をいくつか示します。 引数に指定されたホストにアクセスするスクリプト「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」を候補から外したいとします。 $ 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
肝心なところを隠蔽していてなんじゃこりゃな感じですが、
送信した方に生パスワードらしきモノが見当たらないことが(実際に実行すると)
わかると思います。 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週にして、絶対遅れないようにしたいと思います。 …という決断自体が後ろ向きだとは思いますが、みなさまにおかれましては、 なにとぞ前向きにとらえていただけますと、たいへん幸いです。
今回も、ここまで読んでいただき、超ありがとうございました。
「いますぐ実践! Linux システム管理」の解除は、以下からできます。
バックナンバーは、こちらにほぼ全部そろっています。
「栗日記」- まだ結果に結びついてませんが、毎日、精一杯描いてます。 |
▼ トップ ▼ プロフィール ▼ リンク
▼ 作ってみました
▼ せんでん
▼ 最近読んだ本
▼ 気に入ってる本 |