メインコンテンツへ移動
多くの人が、FTP を使用してファイルを転送するための自動化プロセスを作成しています。その方法はいくつかあり、それぞれに長所と短所があります。このブログでは、さまざまなアプローチについて解説し、それぞれのメリットとデメリットを明らかにします。また、ファイルの転送が不完全になってしまう原因となる問題についても取り上げます。
最も簡単な方法は、ユーザーID、パスワード、およびすべてのFTPリクエストをコマンドマクロに記述し(図1)、それを実行するだけです(図2)。
&attach_input
ftp 172.16.1.116
Noah_Davids
MYPASSWORD
put foo
&if (command_status) ^= 226 &then &goto ERROR1
get bar
&if (command_status) ^= 226 &then &goto ERROR2
quit
&
&label ERROR1
..display_line Could not put file
quit
&return
&
&label ERROR2
..display_line Could not get file
quit
&return

図1 – ftp1.cm – シンプルなコマンドマクロ
ftp1
Connected to 172.16.1.116.
220 phx_vos-m16 FTP server (FTP 1.0 for Stratus STCP) ready. (Compatible with OS
+ TCP/IP)
User (172.16.1.116:Noah_Davids): 331 Password required for nd.
Password:
230 User Noah_Davids.CAC logged in.
200 PORT command successful.
150 Opening data connection for foo (172.16.1.34,49253)0.
226 Transfer complete.
80 bytes sent in 0.01 seconds (6.85 Kbytes/sec)
200 PORT command successful.
550 bar: No such file or directory.
recvrequest: Bad file number.
Get transfer did not complete
Could not get file
221 Goodbye.
図2 – ftp1.cm – 単純なコマンドマクロの実行
この方法の欠点は、ユーザーID、そしてさらに重要なことにパスワードが、マクロの一部として平文で記述されてしまうことです。マクロにアクセスできる人なら誰でも、その内容を確認できてしまいます。2つ目の方法は、.netrcファイルを使用してユーザーIDとパスワードを保存することです(図3)。そして、コマンドマクロ(図4)には、実行するFTPリクエストのみを含めるようにします(図5)。
machine 172.16.1.116
login Noah_Davids
password MYPASSWORD
図3 – .netrcファイル
&attach_input
ftp 172.16.1.116
put foo
&if (command_status) ^= 226 &then &goto ERROR1
get bar
&if (command_status) ^= 226 &then &goto ERROR2
quit
&
&label ERROR1
..display_line Could not put file
quit
&return
&
&label ERROR2
..display_line Could not get file
quit
&return
図4 – ftp2.cm – ユーザーIDとパスワードを指定しないコマンドマクロ
ftp2
Connected to 172.16.1.116.
220 phx_vos-m16 FTP server (FTP 1.0 for Stratus STCP) ready. (Compatible with OS
+ TCP/IP)
331 Password required for nd.
230 User Noah_Davids.CAC logged in.
200 PORT command successful.
150 Opening data connection for foo (172.16.1.34,49256)0.
226 Transfer complete.
80 bytes sent in 0.04 seconds (2.09 Kbytes/sec)
200 PORT command successful.
550 bar: No such file or directory.
recvrequest: Bad file number.
Get transfer did not complete
Could not get file
221 Goodbye.
図5 – ftp2.cm – ユーザーIDとパスワードなしでコマンドマクロを実行する
.netrc ファイルは、そのファイルへのアクセス権を持つのが所有者のみである場合にのみ機能します(図 6)。他の誰かが読み取り権限を持っている場合(図 7)、機能せず、パスワードの入力を求めるプロンプトが表示されます(図 8)。
display_access .netrc -all
%phx_vos#m15_mas>SysAdmin>Noah_Davids>.netrc
w  Noah_Davids.*
n  *.*
図6 – .netrc ファイルの正しい ACL
display_access .netrc -all
%phx_vos#m15_mas>SysAdmin>Noah_Davids>.netrc
w  Noah_Davids.*
r  *.CAC
n  *.*
図7 – .netrc ファイルの不適切な ACL
ftp2
Connected to 172.16.1.116.
220 phx_vos-m16 FTP server (FTP 1.0 for Stratus STCP) ready. (Compatible with OS
+ TCP/IP)
User (172.16.1.116:Noah_Davids): 331 Password required for put foo.
Password:
530 Login incorrect.
Login failed.
221 Goodbye.
図8 – .netrc のアクセス制御リスト(ACL)が正しくない場合のパスワード入力画面
FTPマクロを作成することで、すべてのコマンドを.netrcファイルに記述することができます。マクロの名前を「init」とすれば(図9)、ログイン後に自動的に実行されます。これにより、VOSコマンドマクロはたった1行(図10)のFTPコマンドだけで済みます。 この方法の主な問題は、エラー回復機能がないことです。(command_status) 関数を使用して FTP リクエストの状態を確認することはできません(図 11)。
machine 172.16.1.116
login Noah_Davids
password MYPASSWORD
macdef init
put foo
get bar
quit
図9 – initマクロを含む.netrcファイル
ftp 172.16.1.116
図10 – ftp3.cm – init FTPマクロを含む.netrcファイルと併用する場合のマクロ
ftp3
Connected to 172.16.1.116.
220 phx_vos-m16 FTP server (FTP 1.0 for Stratus STCP) ready. (Compatible with OS
+ TCP/IP)
331 Password required for nd.
230 User Noah_Davids.CAC logged in.
put foo
200 PORT command successful.
150 Opening data connection for foo (172.16.1.34,49276)0.
226 Transfer complete.
80 bytes sent in 0.01 seconds (9.52 Kbytes/sec)
get bar
200 PORT command successful.
550 bar: No such file or directory.
recvrequest: Bad file number.
Get transfer did not complete
quit
221 Goodbye.
図11 – ftp3.cm – initマクロ使用時の出力 – エラー回復なし
私がこれまで見てきたマクロの多くは、ディレクトリにファイルが現れるのを待ち続けるループ処理を行っており、ファイルが現れるとFTPを使って転送します(図12)。
&attach_input
&label AGAIN
&if (exists new_file) = 1 &then &goto FTP
display_line No new_file as of (time)
sleep -seconds 15
&goto AGAIN
&
&
&label FTP
ftp 172.16.1.116
put new_file
&if (command_status) = 226 &then ..display_line OK
&else &do
..display_line
..display_line ERROR
..display_line
&end
quit
図12 – ftp4.cm – ファイルの出現を待機し、その後転送を行うマクロ
この方法の問題点は、FTPがまだ開かれていて書き込み中のファイルを読み取ってしまう可能性があることです。ファイルが大きい場合や、タイミングが悪かった場合、ファイルの一部しか転送されない結果となります(図13)。
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
図13 – ファイルの一部のみが転送される
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
this is the last record
図14 – 完全なファイル
ファイルが存在するかを確認するだけでは不十分であり、ファイルがロックされているかどうかも確認する必要があります(図15)。
&attach_input
&label AGAIN
&if (exists new_file) = 1 & (locked new_file) = 0 &then &goto FTP
display_line new_file not ready for transfer as of (time)
sleep -seconds 15
&goto AGAIN
&
&
&label FTP
ftp 172.16.1.116
put new_file
&if (command_status) = 226 &then ..display_line OK
&else &do
..display_line
..display_line ERROR
..display_line
&end
quit
図15 – ftp5.cm – ファイルの転送前にロックが解除されているかを確認する
したがって、最善の方法は、.netrc ファイルにユーザー ID とパスワードを保存し、各リクエストの後に command_status を確認して実際のリクエストを制御できる VOS コマンドマクロを使用することです。また、ファイルを転送する前に、そのファイルがロックされていないことを確認してください。
SFTPについて疑問に思っている方もいらっしゃるかと思いますが、SFTPを使ったファイル転送の自動化は全く別の話であり、それについては次回のブログで取り上げる予定です。

© 2024 Stratus Technologies.