Everything described below is done via a Bash script.
I desire to capture the state of a defined set of files on a defined set of remote hosts. The "state" of a file depends on the type of file:
- Regular file: full path, content of the file, mode, owner, group
- Symbolic link: full path of the link itself, the pointed-to path, mode (always 777), owner, group
- Directory: full path, mode, owner, group
When creating a local file to represent the state of a remote file, I distinguish between files with the same full path but which differ on different hosts by appending to the local filename a hash of the traits listed above. I then tar the remote file up (non-recursively, so that in the case of a directory, I get just the directory), pipe it though SSH, untar it to my local machine, and mv it to the filename with a hash appended. I use tar because it preserves the traits I care about.
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"
This is all in place and working.
Now, for the case of regular files, I have an additional need to handle sensitive files whose content I don't wish to copy (though the content will continue to be represented in the hash). My goal is to create the exact same local file I would in the process described above, but that the file should be empty rather than contain the content of the remote file.
Note: I cannot copy the file and then empty the copy of content. Being a sensitive file, its content must not be transferred over the network.
I don't know of a way to get tar to transfer a "shell" of a regular file that has the mode, owner, and group of the file but omits the content in the tarball. Unless somebody knows of a trick to get tar to do this, I think I will have to look at some mechanism other than tar.
How can I most easily accomplish this?
UPDATE #1
One approach I'm trying is to first make a temporary copy of the file (using cp -p to preserve the file attributes I care about) on the remote system, empty that temporary file of content (with truncate -s 0), and then copy that to my local machine with tar / ssh as described above. This is awkward and inelegant. I'm hoping to find a way to do this without resorting to the use of a temporary file.