
以下で説明するすべてのことは、Bash スクリプトを介して実行されます。
定義されたリモート ホスト セット上の定義されたファイル セットの状態をキャプチャしたいと考えています。ファイルの「状態」は、ファイルの種類によって異なります。
- 通常ファイル: フルパス、ファイルの内容、モード、所有者、グループ
- シンボリックリンク: リンク自体のフルパス、指し示すパス、モード (常に 777)、所有者、グループ
- ディレクトリ: フルパス、モード、所有者、グループ
リモートファイルの状態を表すローカルファイルを作成するとき、同じフルパスだがホストによって異なるファイルを区別するために、ローカルファイル名に上記の特性のハッシュを追加します。次に、リモートファイルをtarで圧縮します(非再帰的に、ディレクトリの場合は次のようになります)。ただそれをディレクトリにコピーし、SSH でパイプして、ローカル マシンに解凍し、ハッシュが追加されたファイル名に mv でコピーします。tar を使用するのは、必要な特性が保持されるためです。
HASH=$(ssh -n "$ONE_HOST" "{ cat $ONE_FILE_PATH; stat -c \"%a %u %g %F\" $ONE_FILE_PATH; } | sha512sum")
ONE_HASH=${ONE_HASH:0:20}
TARGET_FILENAME_FOR_COPY="$FILENAME"."$ONE_HASH"
TARGET_PATH_FOR_COPY="$TARGET_DIRECTORY_FOR_COPY"/"$TARGET_FILENAME_FOR_COPY"
ssh -n "$ONE_HOST" \
"tar -C $DIRECTORY --no-recursion -cf - $FILENAME" | \
tar -xf - -C "$TARGET_DIRECTORY_FOR_COPY"
mv "$TARGET_PATH_UNHASHED" "$TARGET_PATH_FOR_COPY"
すべて準備が整っており、機能しています。
さて、通常のファイル、内容をコピーしたくない機密ファイルも処理する必要があります (ただし、内容はハッシュで引き続き表されます)。私の目標は、上記のプロセスで作成するのとまったく同じローカル ファイルを作成することですが、そのファイルはリモート ファイルの内容を含むのではなく、空である必要があります。
注: ファイルをコピーして、その内容のコピーを空にすることはできません。機密ファイルであるため、その内容をネットワーク経由で転送してはなりません。
ファイルのモード、所有者、グループを持ち、tarball の内容を省略した通常のファイルの「シェル」を tar で転送する方法を私は知りません。誰かが tar でこれを実行するためのトリックを知っているのでなければ、tar 以外のメカニズムを検討する必要があると思います。
これを最も簡単に実現するにはどうすればいいでしょうか?
アップデート#1
私が試しているアプローチの1つは、まずファイルの一時的なコピーを作成することです(cp -pリモートシステム上のファイル属性を保存するために、一時ファイルの内容を空にします(切り捨て -s 0) を作成し、それを上記のように tar / ssh でローカル マシンにコピーします。これは扱いにくく、洗練されていません。一時ファイルを使用せずにこれを行う方法を見つけたいと思っています。
答え1
tar を実行する前に、機密ファイルの上に空のファイルをマウントすることができます。
touch /tmp/emptyfile
mount --bind /tmp/emptyfile /home/user/.ssh/id_rsa
または似たようなもの。