自動化のスゝメ ~TeraTermMacro編~

  • 2021年3月17日
  • 2021年3月17日
  • negima

単純作業程失敗する

日々様々な環境を構築していると、邪悪な小人の存在によって、思わぬミスが必ず発生します。

 あれ?プログラムが動かない。。。

 ログに表示される日付が世界標準時なんですが。。。

 文字化けガガガガ。。。

etc.etc...

そんな小人から私達を守ってくれる心強い味方が、スクリプトであったり、プログラムであったりするわけです。

というわけで、今回はTeraTermマクロによる自動化を行うにあたって、便利なコマンドやコード等をご紹介していこうと思います。

マクロ実行ディレクトリの取得

自分の環境以外でマクロを実行する場合、問題になるのは外部ファイルの配置場所なことはよくあります。
そこで、マクロが配置されたディレクトリを取得し、そこを起点にファイルを配置すれば、この問題を簡単に解消することができます。

そのコマンドが以下。

getdir [ディレクトリ名保存変数]

使い方は、ローカルファイルを参照する場合、必ず [ディレクトリ名保存変数] を頭に付与するようにして使います。

例)リモートへログイン時、スクリプトのある場所にある、TERATERM_HOGE.INIを読み込む。

HOSTNAME='hoge.com'
USERNAME='hoge'
PASSWORD='fuga'
getdir TTINI_PATH
TTINI_FILE='TERATERM_HOGE.INI'

COMMAND=HOSTNAME
strconcat COMMAND ':22 /ssh /2 /auth=password /user='
strconcat COMMAND USERNAME
strconcat COMMAND ' /passwd="'
strconcat COMMAND PASSWORD
strconcat COMMAND '" /F="'
strconcat COMMAND TTINI_PATH
strconcat COMMAND '\'
strconcat COMMAND TTINI_FILE
strconcat COMMAND '"'

connect COMMAND

SCPコマンドによるファイル転送の待ち方

TeraTermの scpsend コマンドは、非同期でファイル転送を行います。
これではファイルが転送されてからコマンドを実行したい場合に困る為、以下のようなコードを利用してファイル転送の完了を待ちます。

SCP_SEND_PATH='/tmp' …(1)
scpsend 'C:\hogehoge.txt' SCP_SEND_PATH …(2)
pause 2
timeout=5 …(3)
do
 mpause 5000 …(4)
 sprintf "ps -ef | grep '[s]cp -t %s';echo [[${?}]]" SCP_SEND_PATH …(5)
 sendln inputstr …(6)
 pause 1
 wait '[[1]]' …(7)
loop until result=1 …(8)
timeout=0 …(9)
wait ':$' …(10)

上記は、ローカルの c:\hogehoge.txt をリモートの /tmp にコピーし、完了したらプロンプトを待つ処理です。

解説

(1)リモート側のファイル配置先を変数に保管

(2)TeraTermマクロコマンド scpsend によって、ファイル転送開始

(3)wait系コマンドのタイムアウトを5秒に設定(ここはお好みで)

(4)5秒処理を停止

(5)psコマンドでscpコマンドの実行状態をgrepで検索し、一般的に被りにくい文字列+grepコマンドの実行結果を表示するためのコマンドを生成

(6)(5)で作成したコマンドを実行。
※grepコマンドの実行結果は、検索がヒットすれば0を返し、ヒットしなければ1を返す

(7)grepの検索結果がヒットしていないか、タイムアウトまで待つ

(8)waitコマンドの結果、grepの検索結果がヒットしている間(4)~(8)を繰り返す

(9)wait系コマンドのタイムアウトを0(無制限)に戻す

(10)コマンドプロンプトを待つ

本コード実行後は、安全に転送したファイルを操作することができます。

役割毎にファイルを分ける

例えば、以下のような処理のマクロを作るとします。

  1. SSHログインする
  2. Ubuntu18の初期化をする
  3. Dockerをセットアップする

これを1ファイルで作成してもこの時点では問題は浮上しません。

ではここに、

  • A社ではCentOSを使用すること

という要件があった場合、上記をコピーして、2の部分の処理をCentOSのものに書き換える事になると思います。

この時点でもまだ問題は浮上しづらいですが、さらに

  • Dockerのバージョンが上がり、インストールに失敗するようになった

等が出てきた場合、先ほどのUbuntu版と、CentOS版の両方のコードに修正が必要になってしまいました。

今回の例では、上記2つですが、これが他のマクロにも実はDockerのインストールコードがあったとなると、メンテナンスが非常に大変な事になってしまいます。

そこで、上記の処理を以下のようにファイルを分けるとします。

  • SSHログイン.ttl
  • Ubuntu19初期セットアップ.ttl
  • CentOS8初期セットアップ.tll
  • Dockerインストール.ttl

UbuntuでDockerのインストールを行う場合は、

include 'SSHログイン.ttl'
include 'Ubuntu18初期セットアップ.ttl'
include 'Dockerセットアップ.ttl'

となり、
CentOS8でDockerのインストールを行う場合は、

include 'SSHログイン.ttl'
include 'CentOS8初期セットアップ.ttl'
include 'Dockerセットアップ.ttl'

のように、組み合わせることで、マクロを流用しやすくなりますし、Dockerのセットアップで不具合があれば、 Dockerセットアップ.ttl だけを修正すればよくなるため、メンテナンスも容易になります。

対話型処理の処理方法

対話型の処理を行う場合、基本的には対話の流れに沿って、以下のようなコードになると思います。

pause 2
wait '[?] Enter user name :'
sendln 'hogehoge'
wait '[?] Enter password :'
sendln 'fugafuga'
wait '[?] Re-enter password : '
sendln 'fugafuga'
wait ':$'

これは、以下のようなループ文に書き直す事が出来ます。

do
 wait '[?] Enter user name :' '[?] Enter password :' '[?] Re-enter password : ' ':$'
 if result=1 then
  sendln 'hogehoge'
 elseif result=2 || result=3 then
  send ln 'fugafuga'
 elseif result=4 then
  break
 else
  messagebox '予定外のメッセージを受信しました' 'Error'
  end
 endif
loop

例えばループの場合、この例にはないですが、'- 次へ -' のような何度も出てくるプロンプトがある場合、都度書かなくてもよいため、コードがすっきりする半面、コードから流れを追いづらくなるという欠点もあります。

(ループが必要なものだけ切り出して、組み合わせるという手もあります)

どちらのコードが便利かは、その場面場面によるところがあるので、是非使い分けてみてください。

まとめ

いかがだったでしょうか。

割と簡単な処理でもマクロ化しておけば、未来の作業が楽になり、そのマクロをメンテナンスをする事で、過去の資産の更新も容易になる、と、メリットばかりです。

「その場限りの作業だから手作業でいいや」とせずに、どんどんマクロ化し、資産を増やしていきましょう。

それでは、よい自動化ライフを!

最新情報をチェックしよう!

negimaの最新記事8件