Is there a way to move a file and preserve original owner(group) and file mode in one atomic operation? So there will not be change for others to access moved file in time when is not already set original owner or mode?
Filesystem is XFS.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityThe requirement now stands as a mv
operation on a file, or tree of files, within the same filesystem.
This satisfies the atomicity and ownership/group requirements. It will also retain setgid and sticky-bit flags if the operation is performed as the root
user. For normal files and directories any user can move then provided they have read+write+execute permission to the source and destination parent directories (i.e. old
and new
in this example):
mv /path/to/old/source /path/to/new/destination
See POSIX mv and POSIX rename for the precise detail.
If you're moving the file withing the same filesystem, then mv
is an atomic operation. Up to a point, the file is at its old location; after that point the file is at its new location. The entry for the file in the old directory is removed, and a new one is added to the new directory, in a single operation. The entry is not just the file content but the whole inode, including the file metadata such as the owner and permissions. There is no point at which the permissions are modified.
If you're moving the file to a different filesystem, then the operation is not atomic: it involves creating a new file, then modifying both its contents and its metadata until they match the old file, and removing the old file. A new file is always created empty and belonging to the user who created it. The creator can set the traditional Unix permissions as soon as the file is created, but not access control lists.
You can control the initial owner, group and mode of the new file by running mv
as the desired owner and group and setting umask
to the complement of the permissions of the file. Here's a Linux shell method, assuming the user and group exist and have a Bourne-style shell as their login shell:
set $(stat -c '%U %G %a' "$original_file")
export user=$1 group=$2 mode=0$3 original_file destination
su "$user" -c 'sg "$group" -c "umask $((07777 & ~mode)) && touch "$destination" && mv -- "$original_file" "$destination"'
This is pretty fiddly, and the file will be created with the right ownership and permissions but different contents, different timestamps, etc. If you don't want the file to be visible until it's fully reproduced, first move the file to a temporary directory on the destination filesystem which is visible only to root, then atomically move the file into place.
d=$(TMPDIR="$(dirname -- "${destination}")" mktemp -d)
chmod 700 "$d"
mv -- "$original" "$d/file"
mv -- "$d/file" "$destination"
rmdir d
These are some ways to do it; although not atomic, should be safe enough for your needs.
You could copy the file using the -p
flag to preserve permissions and ownership, then remove the original file: cp -p /old/path/file /new/path/ && rm -f /old/path/file
You could use rsync: rsync -pogXA --remove-source-files /old/path/file /new/path/
If you're the root user, you could chmod 000
the file, move it, then restore the appropriate owner and permissions.
000
permissions.
mv
doesn't change the owner.