ターミナルで何でも行う人にとって、FTP の GUI クライアントはもう辛すぎるのです。 コマンド1つで rsync のようにアップロードしたいのです。
同じように考える人は多いらしく、 “rsync”, “FTP” でググると “rsync over FTP” がどうのこうのと書かれた記事は散見するものの、 そんなものないけど、代わりに lftp 使うといいよ。みたいな記事が多くあります。
なので、(過去に1度使った記憶あるものの、改めて)試しに使ってみました。
なお、MacBook Pro の El Capitan です。Homebrew でインストールします。
brew install lftp
man lftp
lftp コマンドは、基本的に ftp コマンドと同じく対話形式のコマンドなのですが、 オプションで -e や -c とともに対話形式の内容のコマンド(サブコマンド?)をつけてやると そのまま実行できます。
また、対話形式をテキストファイルにまとめておき、 -f オプションで利用することも可能です。 以下は lftp コマンド自体のシンタックスとオプションです。(man lftp より抜粋)
SYNTAX
lftp [-d] [-e cmd] [-p port] [-u user[,pass]] [site]
lftp -f script_file
lftp -c commands
lftp --version
lftp --help
OPTIONS
-d Switch on debugging mode.
-e commands
Execute given commands and don't exit.
-p port
Use the given port to connect.
-u user[,pass]
Use the given username and password to connect. Remember to
quote the password properly in the shell. Also note that it is
not secure to specify the password on command line, use ~/.netrc
file or LFTP_PASSWORD environment variable together with
--env-password option. Alternatively you can use ssh-based pro-
tocols with authorized keys, so you don't have to enter a pass-
word.
--norc Don't execute rc files from the home directory.
-f script_file
Execute commands in the file and exit. This option must be used
alone without other arguments (except --norc).
-c commands
Execute the given commands and exit. Commands can be separated
with a semicolon, `&&' or `||'. Remember to quote the commands
argument properly in the shell. This option must be used alone
without other arguments (except --norc).
上記から、接続情報は lftp のオプションとして渡しつつ、 それとは別に対話形式内のコマンドにて実際のファイルアップロードを行います。
今回はその中の mirror コマンドを利用し、 rsync に近いことを行ったのを シェルスクリプトにまとめてみました。(接続情報はダミー)
#!/bin/sh
HOSTNAME=192.0.2.24
USERNAME=girigiribauer
PASSWORD=passwordhere
SOURCE="path/to/source_dir"
DIST="/path/to/target_dir"
lftp -d -u $USERNAME,$PASSWORD $HOSTNAME -e "\
mirror \
--reverse \
--delete \
--only-newer \
--verbose \
-X .DS_Store \
$SOURCE \
$DIST; \
exit"
後半が mirror コマンドのオプションですが、 reverse はアップロードを意味します。
色々オプションあるので詳しくはヘルプを見た方が良いのですが、
lftp の方のヘルプにはあまり詳しく載ってませんので
lftp コマンドをそのまま実行して対話形式にしてから
help mirror
とすることで mirror コマンドの help を開くことができます。
% lftp
lftp :~> help mirror
Usage: mirror [OPTS] [remote [local]]
Mirror specified remote directory to local directory
-c, --continue continue a mirror job if possible
-e, --delete delete files not present at remote site
--delete-first delete old files before transferring new ones
-s, --allow-suid set suid/sgid bits according to remote site
--allow-chown try to set owner and group on files
--ignore-time ignore time when deciding whether to download
-n, --only-newer download only newer files (-c won't work)
-r, --no-recursion don't go to subdirectories
-p, --no-perms don't set file permissions
--no-umask don't apply umask to file modes
-R, --reverse reverse mirror (put files)
-L, --dereference download symbolic links as files
-N, --newer-than=SPEC download only files newer than specified time
-P, --parallel[=N] download N files in parallel
-i RX, --include RX include matching files
-x RX, --exclude RX exclude matching files
RX is extended regular expression
-v, --verbose[=N] verbose operation
--log=FILE write lftp commands being executed to FILE
--script=FILE write lftp commands to FILE, but don't execute them
--just-print, --dry-run same as --script=-
When using -R, the first directory is local and the second is remote.
If the second directory is omitted, basename of first directory is used.
If both directories are omitted, current local and remote directories are used.
今回は、手元のファイルのが新しい場合に動作し、 なおかつ手元で削除したファイルも同期を取りたいので、 –delete と –only-newer オプションをつけました。
FTP だけでも rsync にある程度近いことは出来ました。
ただ、 dry-run 相当のオプションが探した限りなかったので、 実際に試しながら正しく動作しているか確認することになるので、 そこはちょっと怖いところではありますね・・・。
2016/09/30追記
さーせん、dry-run オプションありました・・・
–just-print, –dry-run same as –script=- って上にあるじゃん、自分の目はフシ穴か・・・
2016/09/30追記ここまで
FTP のみという縛りがあったとしても、コマンド1つで転送できるようにしておけば、 バージョン管理などと連携してフックさせることも可能となり、 精神衛生的にも良いかと思います。
この記事は書かれてから1年以上が経過しており、最新の情報とは異なる可能性があります