複数コマンドの出力をまとめてパイプに流す

  • 複数コマンドの出力をまとめてパイプに流す

複数コマンドの出力をまとめてパイプに流し込みたいときは、 "{}" によるコマンドのグルーピング機能を利用する。

{ echo "hogehoge"; echo "fugafuga"; } | wc -l
→ "{}" で複数コマンドをグループ化することにより出力を一つにまとめる。

コマンドの数が多い場合は、次のように記述すると可読性が高くなる。

{
date
echo "hoge"
echo "HOGE"
echo "fuga"
echo "FUGA"
} | tee -a file

expectについての良Blogエントリ

(参照URL)http://www.e-bellnet.com/technical/hint/0911/hint_0911_01.html

Q:
助けてください。困っています。SFTP でドキュメントを送信するときに、あなたの記事を参考に Expect スクリプトを作成している者です。すべて計画どおり進んでいるときは問題ないのですが、うまくいかなくなると、Expect スクリプトが止まらなくなり、CL プログラムにエラーも報告されません。終了ステータスはゼロです。いろいろなところを探して答えを見つけようとしました。


A:
その通り、OpenSSH の SFTP ユーティリティーは、失敗するとその呼出元へゼロ以外の終了ステータスを戻します。しかし、SFTP を呼び出しているのはあなたの CL プログラムではありません。Expect スクリプトが呼び出しているのです。したがって、Expect スクリプトがエラーを検出せず、CL プログラムにゼロを戻している場合、CL プログラムには何かが失敗したことを告げる術はありません。

この記事では、エラー処理を Expect スクリプトに追加する方法と Expect に対して CL プログラムへエラーを報告させる方法について説明します。

確認: オリジナル・スクリプトの動作
基本的に知っておくべきことは Expect スクリプトは文字列を検索することで動作するということです。それらのスクリプトはじっくり SFTP (または制御している何らかのプログラム) からのデータを読み取って、そのデータをバッファーに追加し、そのバッファーの中で捜し物をします。ほとんどの Expect がそのように、読み取って比較、読み取って比較、読み取って比較を繰り返します。

では、Expect はデータが到着しないのと、エラーと見なすものの違いはどのようにわかるのでしょうか。わかりません。SFTP が終了したときにわかり、タイムアウトが発生したときにわかります。それらはエラーと見なされるはずです。もしくは、検索している文字列が見つからなかったことがわかるだけです。

以下の Expect スクリプトの例は以前の記事に載せた例ですが、左側に行番号を追加しています。

  #!/usr/local/bin/expect -f
1 spawn sftp klemscot@ssh.example.com
2 expect "Connecting to ssh.example.com..."
3 expect "Password:"
4 send "bigboy\n"
5 expect "sftp>"
6 send "put myfile.csv\n"
7 expect "sftp>"
8 send "quit\n"
9 exit

手始めとして、この例はできるだけ簡単にしました。動作の内容は以下のとおりです。

spawn コマンドが sftp プログラムを起動し、そのプログラムを ssh.example.com に接続し userid klemscot としてサインインするよう指示します。
文字列「Connecting to ssh.example.com...」が見つかるまでひたすら待ちます (ループで「読み取り比較」)。
文字列「Password:」が見つかるまでひたすら待ちます (「読み取り比較」)。
パスワード「bigboy」に続いて Enter キーを示す \n を送信します。
文字列「sftp>」が表示されるまでひたすら待ちます。
文字列「put myfile.csv\n」を送信します。
「sftp>」を再度じっくり待ちます。
「quit\n」を送信します。
呼出元にゼロを戻し、Expect スクリプトを終了します。
分かりやすいですが、それで十分でしょうか。答えはおそらくノーでしょう。予期しないメッセージが表示された場合でも Expect は相変わらず待つだけで、絶望のふちで、期待するよう指示した文字列を取得することをひたすら願っているからです。

他の条件の確認
幸いにも、これよりもっと良いことができます。expect キーワードは、上記で示したように、1 つの文字列だけを待つわけではありません。複数の文字列を待ち、どれを受信するかによって個別に対応ができます。SFTP プログラムが終了したり、予想した文字列が適切な時間内に表示されない場合に必ず行われる「デフォルト」動作を設定することもできます。例えば、スクリプトの最初の数行が次のようになっていると思ってください。

#!/usr/local/bin/expect -f
set timeout 20
spawn sftp klemscot@ssh.example.com
expect {
  default {exit 2}
  "Connecting to ssh.example.com..."
}

「set timeout 20」により 20 秒後にタイムアウトします。以前のように SFTP を spawn しますが、「expect」コマンドが完全に違う点に注目してください。波括弧は、待つ文字列のグループを示します。この例では、文字列「Connecting to ssh.example.com...」が見つかるか、デフォルト動作と行うという 2 つのオプションがあります。デフォルト動作は、タイムアウト期間になるか、SFTP が終了すると発生します。「exit 2」がデフォルト動作の下にリストされる点に注目してください。これは Expect に終了し、終了ステータスを 2 に設定するよう指示します。CL プログラムが終了ステータスを確認している場合、番号 2 を参照し、何か問題が起きたことを認識します。

接続後、かつてのスクリプトは文字列「Password:」を待ってから、パスワードを送信しました。しかし、それには問題があります。パスワードのスペルが大文字の P になっていたり、小文字になっている場合があるのです。このスクリプトには別の問題もあります。最初に指定のホストに接続すると、本当に接続するかどうか尋ねてきます。そのプロンプトが表示されると、まだ「読み取り比較」モードで「Password:」を検索しているため、オリジナルのスクリプトは混乱します。私は以下のようにそれを解決しました。

expect {
 default {exit 2}
  "continue connecting (yes/no)?" {send "yes\n"; exp_continue}
  "assword:"
}
send "bigboy\n"

おわかりのように、デフォルト動作を追加しました。したがって、タイムアウトになったり SFTP が終了すると、終了ステータス 2 で Expect スクリプトを終了させます。さらに、2 つの異なる文字列を待つようスクリプトに指示しました。1 つは接続を継続するかどうか確認する文字列で、もう 1 つは実際のパスワード・プロンプトです。「continue connecting」プロンプトが表示されたら、「yes&92;n」が、次に「exp_continue」が送信されます。これは同じ expect ステートメントを継続するよう指示しています。これにより「読み取り比較」モードに戻るため、パスワード・プロンプトが最終的に表示されるか、デフォルト動作が行われるまでスクリプトは待ち続けます。

これでわかったと思います。デフォルト条件だけでなく、参照しようとするものそれぞれの条件を個別にコーディングすることで、発生するあらゆるさまざまな物事に対応し、エラー処理をスムーズに行うことができます。

すべてをまとめる
スクリプトを更新したものを丸ごと以下に示します。

#!/usr/local/bin/expect -f
set timeout 20
spawn sftp klemscot@ssh.example.com
expect {
 default {exit 2}
  "Connecting to ssh.example.com..."
}
expect {
 default {exit 2}
  "continue connecting (yes/no)?" {send "yes\n"; exp_continue}
  "assword:"
}
send "bigboy\n"
expect {
 default {exit 2}
  "sftp>"
}
send "put myfile.csv\n"
expect {
 default {exit 2}
  "not found" {exit 3}
  "sftp>"
}
send "quit\n"
exit 0

Cisco 3750 初期化

Catalyst 3750の初期化手順

スイッチのmodeボタンを押しっぱなしのまま電源を投入
LED がオレンジ色の点滅から緑色の点灯に変わったら、Mode ボタンを放す

flash_initコマンドを実行
switch: flash_init
Initializing Flash...
flashfs[0]: 419 files, 8 directories
flashfs[0]: 0 orphaned files, 0 orphaned directories
flashfs[0]: Total bytes: 15998976
flashfs[0]: Bytes used: 15028736
flashfs[0]: Bytes available: 970240
flashfs[0]: flashfs fsck took 10 seconds.
...done Initializing Flash.

dir flash: コマンドを実行

switch: dir flash:
Directory of flash:/

91 drwx 192 c3750-ipservicesk9-mz.122-50.SE
5 -rwx 14799 config.text
6 -rwx 796 vlan.dat
7 -rwx 2072 multiple-fs
428 -rwx 1940 private-config.text

970240 bytes available (15028736 bytes used)



switch: dir flash:
コンフィギュレーション ファイル名を変更
switch: rename flash:config.text flash:config.bak

switch: ren flash:config.text flash:config.text.bak

ファイル名が変更されたか確認
switch: dir flash:
Directory of flash:/

91 drwx 192 c3750-ipservicesk9-mz.122-50.SE
5 -rwx 14799 config.text.bak
6 -rwx 796 vlan.dat
7 -rwx 2072 multiple-fs
428 -rwx 1940 private-config.text

970240 bytes available (15028736 bytes used)



システムをブート
switch: boot

ading "flash:c3750-ipservicesk9-mz.122-50.SE/c3750-ipservicesk9-mz.122-50.SE.bin"...@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Cisco IOS Software, C3750 Software (C3750-IPSERVICESK9-M), Version 12.2(50)SE, RELEASE SOFTWARE (fc1)
Copyright (c) 1986-2009 by Cisco Systems, Inc.
Compiled Sat 28-Feb-09 03:33 by weiliu
Image text-base: 0x00003000, data-base: 0x01D00000

Initializing flashfs...

flashfs[1]: 419 files, 8 directories
flashfs[1]: 0 orphaned files, 0 orphaned directories
flashfs[1]: Total bytes: 15998976
flashfs[1]: Bytes used: 15028736
flashfs[1]: Bytes available: 970240
flashfs[1]: flashfs fsck took 2 seconds.
flashfs[1]: Initialization complete....done Initializing flashfs.
Checking for Bootloader upgrade.. not needed

POST: CPU MIC register Tests : Begin
POST: CPU MIC register Tests : End, Status Passed

POST: PortASIC Memory Tests : Begin
POST: PortASIC Memory Tests : End, Status Passed

POST: CPU MIC interface Loopback Tests : Begin
POST: CPU MIC interface Loopback Tests : End, Status Passed

POST: PortASIC RingLoopback Tests : Begin
POST: PortASIC RingLoopback Tests : End, Status Passed

Waiting for Stack Master Election...
POST: PortASIC CAM Subsystem Tests : Begin
(以下省略)
.
.
.
.
.
Would you like to enter the initial configuration dialog? [yes/no]: no

上記メッセージが出たら”no”を選択

enableモードに入る
Switch>enable
Switch#

setupを実行して初期設定コマンドを実行
Switch# setup

kshでbash風の履歴表示をさせる

kshでは上矢印キー左/右/下矢印キーを入力した際に、
最後に入力したコマンドではなく制御文字が表示される

これをbash風にするには「set -o emacs」という一行を
/etc/.kshsrcに追記する

ftp自動ログイン

open hostname
user xxxx
password:
cd <directory>
bin or ascii
get <filename>
bye
この書き出したコマンドを自動的に実行するには、コマンドライン、または、シェルスクリプトの中で以下のようにコマンドを実行します。

ftp -n < ftp.txt