読者です 読者をやめる 読者になる 読者になる

カタカタブログ

SIerで働くITエンジニアがカタカタした記録を残す技術ブログ。Java, Oracle Database, Linuxが中心です。たまにRuby on Railsなども。

FTPとのファイル連携はcurlコマンドが便利

未だにFTPサーバとファイルのやりとりをせざるを得ない場合は(それほど多くはないが、残念ながら)まだある。しかし、ftpコマンドは対話式のコマンドでやりとりするため使いづらい。特にシェルスクリプトでやろうとすると、コマンドを流し込んだり、エラーハンドリングしたりが非常にやりづらかった。

そんなとき、curlコマンドを使うととても便利である。curlはhttp(s)で使うイメージが強いが、実はftpにも対応している。しかも、ftpコマンドと違ってcurlの場合はパスとオプションにより、1コマンドで簡潔するためシェルスクリプトでも使いやすい。そんな、curlコマンドからFTPとやりとりする方法についてまとめる。

なお、今回はCent OS 7にFTPサーバ(vsftpd)をたて、Mac OS Xからcurlコマンドを実行して検証したが、他のOSでもほとんど変わらないと思う。

ディレクトリ確認

ftp://と続けてディレクトリを指定すると、そのディレクトリのファイル一覧が見れる。

$ curl -u <user>:<password> ftp://<host>/<path to directory>
  • 実行例
$ curl -u vagrant:vagrant ftp://vmora7
drwxrwxr-x    2 1000     1000           21 Apr 15 13:03 ftpwork

ファイル取得

ftp://と続けてファイルパスを指定すると、ファイルの中身を標準出力に表示する。

$ curl -u <user>:<password> ftp://<host>/<path to file>
  • 実行例
$ curl -u vagrant:vagrant ftp://vmora7/ftpwork/test.txt
contents of test.txt

ファイルダウンロード(複数も可能)

  • Oオプションを指定することでダウンロードすることができる。また、数値の範囲指定も可能。

ちなみに-lオプションをつけると、ファイルサイズが0バイトのものもダウンロードする。

$ curl -u <user>:<password> -l -O ftp://<host>/<file>
  • 実行例
$ curl -u vagrant:vagrant -l -O ftp://vmora7/ftpwork/file[1-3].txt

[1/3]: ftp://vmora7/ftpwork/file1.txt --> file1.txt
--_curl_--ftp://vmora7/ftpwork/file1.txt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0    54    0     0    796      0 --:--:-- --:--:-- --:--:--   805
[2/3]: ftp://vmora7/ftpwork/file2.txt --> file2.txt
--_curl_--ftp://vmora7/ftpwork/file2.txt
  0     0    0    54    0     0  47120      0 --:--:-- --:--:-- --:--:-- 47120
[3/3]: ftp://vmora7/ftpwork/file3.txt --> file3.txt
--_curl_--ftp://vmora7/ftpwork/file3.txt
  0     0    0    54    0     0  45762      0 --:--:-- --:--:-- --:--:-- 45762

ファイルアップロード

  • Tオプションでローカルファイルパスを指定すると、ファイルアップロードができる。

ダウンロードと同様に、複数ファイルにも対応している。

$ curl -T <file> -u <user>:<password> ftp://<host>//<dir>
  • 実行例
$ curl -T test.txt -u vagrant:vagrant ftp://vmora7/ftpwork/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    13    0     0  100    13      0    157 --:--:-- --:--:-- --:--:--   158

ちなみにftpコマンドの場合

これをftpコマンドの対話式コンソールの場合だと以下のようになる。
curlに比べるととても複雑。しかもコマンドも決して覚えやすいものではない(もっとも、覚えやすくないのはcurlのオプションも同じだが。。)

$ ftp -nv
ftp> open vmora7 ★接続
Connected to vmora7.
220 (vsFTPd 3.0.2)
ftp> user vagrant vagrant ★ログイン
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd ftpwork ★ディレクトリ移動
250 Directory successfully changed.
ftp> ls ★FTPサーバ上のファイル確認(なにもない)
229 Entering Extended Passive Mode (|||16374|).
150 Here comes the directory listing.
226 Directory send OK.
ftp> put test.txt ★ファイルアップロード
local: test.txt remote: test.txt
229 Entering Extended Passive Mode (|||18001|).
150 Ok to send data.
100% |***********************************************|    16      183.82 KiB/s    00:00 ETA
226 Transfer complete.
16 bytes sent in 00:00 (11.12 KiB/s)
ftp> ls ★アップロードされたことを確認
229 Entering Extended Passive Mode (|||20153|).
150 Here comes the directory listing.
-rw-r--r--    1 1000     1000           16 Apr 15 13:03 test.txt

226 Directory send OK.

まとめ

FTPサーバとのファイルアップロードやダウンロードはcurlコマンド一発で実現できる。複数ファイルにも対応できる(ただしワイルドカードは無理っぽい?)ので、基本的な処理はftpコマンドの代わりとして十分に使えるはず。特にシェルスクリプトの場合は、ftpコマンドをあらかじめ全て記載してヒアドキュメントなどでいっきに流し込む必要があるが、そうするとエラーハンドリングがとても難しい。しかしcurlならばcurlコマンド一発なのでリターンコードを見るだけでOK。

FTPサーバとのやりとりにはcurlコマンドが便利!

以上。