はじめに

Tera Termではscp機能が使用できるが、Tera Termマクロのscp受信コマンド scprecv とscp送信コマンド scpsend で同機能が使える。
通常はバッチファイルからSFTPを自動で実行するで書いたWinSCPを使用してファイルダウンロードする方が簡単かつメリットがあるが、Tera Termマクロの柔軟な機能を使用したい時などは、Tera Termマクロ + WinSCPよりもTera Termマクロだけで完結させた方がシンプルになる。

※WinSCP側のメリット

  • Tera Termと違って受信機能が同期で動くため、受信完了のタイミングを考えなくてもよい。
  • サーバへのログインパスワードがWinSCP側で保存でき、平文でスクリプトファイルに書く必要がない。

それではTera Termマクロを使用した、サーバと端末間でのファイルの送受信方法の解説を行う。

サーバから端末へのダウンロード方法その1

WinSCP側のメリットで書いた通り、Tera Termマクロでは受信機能が非同期で動くため、受信完了のタイミングを考えなくては上手くダウンロードができない。

受信が完了したと判断するロジックを、ここでは次のようにする。

「1秒ごとに端末のファイルサイズを確認し、変動がなくなれば完了」

サンプルとして、サーバの/tmp/sample.csvを端末のC:\work\にダウンロードするTera Termマクロを、このロジックを使って書き、バッチから呼び出す。

callscpresv.bat

set TTLEXE="C:\Program Files\teraterm\ttpmacro.exe"
:必ずフルパスでファイル指定する
set TTLFILE=C:\work\rack_remove_comp.ttl

%TTLEXE% %TTLFILE%

scprecv.ttl

hostname = 'HOST名もしくはIPアドレス'
portnum = '22'
username = 'ユーザ名'
userpasswd = 'パスワード'

localdir = 'C:\work\'
remotedir = '/tmp/'
filename = 'sample.csv'
; ローカルファイルフルパス
localpath = localdir
strconcat localpath filename
; リモートファイルフルパス
remotepath = remotedir
strconcat remotepath filename


; ログインコマンド組立て
msg = hostname
strconcat msg ':'
strconcat msg portnum
strconcat msg ' /ssh /auth=password /user='
strconcat msg username
strconcat msg ' /passwd='
strconcat msg userpasswd

; 接続
connect msg

; 接続判定1(接続出来ない場合はメッセージを表示しマクロ終了)
if result <> 2 then
    messagebox 'It could not be connected.' 'Connection Error'
    end
endif

; 接続判定2(10秒以内にプロンプトが表示されない場合TeraTerm終了)
timeout = 10
wait '$' '#'
if result=0 then
    disconnect 0
    end
endif

; 受信ファイルが存在する場合削除
filesearch localpath
if result then
    filedelete localpath
endif

; ファイル受信
scprecv remotepath localpath
;受信完了確認(scprecvが非同期処理のため)
; 参考 http://qiita.com/KurokoSin/items/b4d2d0a81c8d05f110ef
; 1秒ごとに端末のファイルサイズを確認し、変動がなくなれば完了としている
mpause 1100
sizeBef = 0
:confirm_start
    filestat localpath sizeNow
    if sizeNow = sizeBef then
        goto confirm_end
    else
        mpause 1100
    endif
    sizeBef = sizeNow
    goto confirm_start
:confirm_end

; マクロ終了
sendln 'exit'
end

サーバから端末へのダウンロード方法その2

受信が完了したと判断するロジックを、方法その1より洗練させ、次のようにする。

「scp中のサーバのプロセスを確認し、プロセスが消えれば完了」

端末がファイルを受信する scprecv コマンドを実行すると、サーバでは scp -f scprecvの第一引数(remotepath) というプロセスが動く。ps -efをgrepしてマッチした行数をgrepの-cオプションで表示し、表示が「0」になったらプロセスが消えたと判断する。

お題は方法その1と全く同じとして、 scprecv.ttl のファイル受信部分のみ、今回のロジックを使い以下に変更する。

; ファイル受信
scprecv remotepath localpath
;受信完了確認(scprecvが非同期処理のため)
do
    mpause 2000
    sendln 'ps -ef | grep -v grep | grep -c "scp -f ' remotepath '"'
    recvln ;上のコマンドを受信
    recvln ;上のコマンドの実行結果である標準出力を受信
    strcompare inputstr '0' ;受信した標準出力が'0'と等しければresult=0
loop while result != 0;

サーバのプロセスを見て判断しているため、端末でのファイルサイズ確認よりネットワーク状況等の都合を受けず、安定して受信完了を判定できる。

端末からサーバへのアップロード方法

受信方法について説明してきたので、次は送信方法について書きたい。

送信も受信と同様、Tera Termマクロでは非同期で動くため、送信完了のタイミングを考えなくては上手くアップロードができない。

送信完了を判定するロジックは、ダウンロード方法その2と同様に考えればよい。

「scp中のサーバのプロセスを確認し、プロセスが消えれば完了とする」

送信用コマンド scpsend を実行すると、サーバでは scp -t scpsendの第二引数(remotepath) というプロセスが動く。

localpath と remotepath に前回までと同様に適切なファイルパスが入っているとして、localpath にあるファイルを remotepath にアップロードするサンプルを、ファイル送信部分に絞って以下に記載する。

; ファイル送信
scpsend localpath remotepath
do
    mpause 2000
    sendln 'ps -ef | grep -v grep | grep -c "scp -t ' remotepath '"'
    recvln ;上のコマンドを受信
    recvln ;上のコマンドの実行結果である標準出力を受信
    strcompare inputstr '0' ;受信した標準出力が'0'と等しければresult=0
loop while result != 0;