©️

rsyncの”新機能”: --mkpathオプションについて

2024/02/11に公開

rsyncとは

公式ページのrsyncコマンドに関する最初の段落を引用します:

Rsync is a fast and extraordinarily versatile file copying tool. It can copy locally, to/from another host over any remote shell, or to/from a remote rsync daemon. It offers a large number of options that control every aspect of its behavior and permit very flexible specification of the set of files to be copied. It is famous for its delta-transfer algorithm, which reduces the amount of data sent over the network by sending only the differences between the source files and the existing files in the destination. Rsync is widely used for backups and mirroring and as an improved copy command for everyday use.
[https://download.samba.org/pub/rsync/rsync.1]

Rsyncは高速で多種多様なfileコピーを実現するツールです。ローカル、別のremoteシェルを経由して別のホスト、remoteにあるrsync daemonに対しての双方向でのコピーができます。またrsyncのふるまいの制御や、コピーするfileについての柔軟な仕様の設定を可能にする数多くのオプションを提供します。実装されているdelta-trasferアルゴリズムは、コピー元のfileとコピー先の存在しているfileの差分のみを送信することで、通信量を減らすことができます。Rsyncはバックアップやミラーリングに広く使われ、通常のコピーコマンドの上位互換です。(著者意訳)

このようにfileを同期するために用いられるtoolになっています。どうやらcpコマンドやscpコマンドの上位互換と考えてよさそうです。

--mkpathについて

--mkpathはrsyncの3.2.3 (6 Aug 2020)にて導入された比較的新しいコマンドです。これまでfileをコピーする際に、コピー先のディレクトリが存在しなかったとき、

$rsync -av ./test_file.txt name@host_name:/home/name/folder1/folder2/folder3/
rsync: [Receiver] mkdir "/home/name/folder1/folder2/folder3/" failed: No such file or directory (2)

のように表示されてしまい、コピーに失敗してしまいます。そのとき--mkpathをオプションを付与指定実行すると実行できます。

問題点

rsyncはローカル側とリモート側の双方にソフトが入っている必要があり、--mkpathオプションを利用するにはともにversionが33.2.3以上である必要があります。

リモート側にも管理者権限があり、自由にソフトを入れられる場合は、

sudo apt instll rsync

などのコマンドを実行することで最新のrsyncを入れることができるでしょう。しかし場合によっては管理者権限を持っていない場合があります。その場合はソースビルドをしてローカルにインストールし、システムのrsyncコマンドを上書きすることで対処することができます。ここでは、$HOME/.local/以下にインストールして、pathを通す例を紹介します。

公式ホームページからsourceをdownloadします。ここでは最新の安定バージョンであるversion3.2.7をインストールする例を紹介しますが、将来より高いversionが公開されている場合はそちらを利用するとよいかもしれません。

"rsync-3.2.7.tar.gz"という文字列を右クリックしてリンクをコピーし、remoteのターミナルでwgetを実行します。

$wget https://download.samba.org/pub/rsync/src/rsync-3.2.7.tar.gz

その後以下のコマンドを実行します。

tar -xf rsync-3.2.7
cd rsync-3.2.7
mkdir build
cd build
../configure --help

するとinstallに関するオプションが表示されるでしょう。ここでは管理者権限なしでのinstallをするので、--prefix=$HOME/.local/を付与します。

../configure --prefix=$HOME/.local/

で実行します。その結果、

Configure found the following issues:

- Failed to find xxhash.h for xxhash checksum support.
- Failed to find zstd.h for zstd compression support.
- Failed to find lz4.h for lz4 compression support.

See the INSTALL file for hints on how to install the missing libraries and/or
how to generate (or fetch) man pages:
    https://github.com/WayneD/rsync/blob/master/INSTALL.md

To disable one or more features, the relevant configure options are:
    --disable-xxhash
    --disable-zstd
    --disable-lz4

configure.sh: error: Aborting configure run

などが表示されるかもしれません。その場合はエラーメッセージに従い、

rm -rf *
../configure --prefix=$HOME/.local/  --disable-xxhash --disable-zstd  --disable-lz4

を実行すると楽でしょう。もちろんinstallされていないxxhashなどのライブラリを別途入れるという対応も可能です。実行が終わりbuildが成功したら、installします。

make

完了したらbuildが成功したかの確認をします。

make check

failしたテストが看過できるものでしたら、(私の場合、複数の環境でinstallしましたがそのうち一つはdiff関連のテストに失敗していました。)

make install

を実行しインストールします。

次に環境変数を定義します。多くの環境ではデフォルトで$HOME/.local/binにはpathが通っているため何もしなくても使える可能性はあるのですが、そうではない場合は、.bashrc

export PATH="$HOME/.local/bin:$PATH"

を追記します。その後

source ~/.bashrc

を実行して設定を反映します。すると新しいversionのrsyncが利用できるようになっているでしょう:

$rsync --version
rsync  version 3.2.7  protocol version 31
Copyright (C) 1996-2022 by Andrew Tridgell, Wayne Davison, and others.

これでinstall完了です。

rsync --help | grep mkpath

とするとversionが正しければ何かしら引っかかるようになるでしょう。

localから--mkpathオプションを付けて先ほどのコマンドを実行してみましょう:

rsync -av ./test_file.txt name@host_name:/home/name/folder1/folder2/folder3/

すると再帰的にdirectoryが生成されてisntallできるでしょう。

おわりに

ここまで読んでくださってありがとうございます。私はrsyncを開発環境と計算資源の間の同期に使うために導入しました。sftpなどのツールをそれまで使っていたのですが、putgetコマンドでやり取りするのが面倒であったことから同期に心理的障壁が生じ結局それぞれの環境で独立してコードを書いていました。しかし計算資源が複数になるとそのような管理方法では各計算資源でそれぞれ独自のデータが生成されてしまい、分析が難しくなってきて別の手段を編み出す必要が出てきました。

一番最初に目がついたのはvscodeのsftp拡張機能だったのですが、複数のホストに同時に共有する機能が充実していなかったり、syncのコマンドがあまりに隣接しすぎていて間違って逆の操作をしてデータを吹き飛ばしてしまいそうであったので利用できないとなり、手動でsyncするツールを作ることにしました。その際にrsyncに出会ったのですが前述のような問題に直面してしまい、かなり解決に時間を使ってしまいました。そこでここで共有することにしました。

皆さんの開発・研究がより一層進むことを願い、本文章を終えたいと思います。

Discussion