It's impossible to exclude partial files because there's no such concept. As soon as the producer has created the file, the file exists, but it starts out empty and gets filled gradually.
You can test whether the file is open for writing; that would tell you that it's incomplete. However this is not reliable: if the producer crashes (either the process crashes or the whole system crashes), you're left with an incomplete file that looks complete.
What you should do is define a protocol for the producer to mark the file as complete. The normal way to do this (and pretty much the only sane way) is for the producer to create the file in a temporary location, then move it into place (with a rename
system call or the mv
shell command) when it's finished.
You can use a naming convention:
Producer: write to $FILENAME.tmp
, then move to the final file.
generate_data >"dir/$FILENAME.tmp"
mv "dir/$FILENAME.tmp" "dir/$FILENAME"
Consumer: exclude .tmp
files.
rsync -a --exclude='*.tmp' dir remote:
Or you can use a staging directory.
Producer: write to the staging directory, then move to the final location.
generate_data >"dir/staging/$FILENAME"
mv "dir/staging/$FILENAME" "dir/"
Consumer: exclude the staging directory.
rsync -a --exclude='/staging' dir remote: