Setting ownership when copying or syncing files
In zsh
, you could always do (as root
) something like:
(cd tmp/ftp && tar cf - new-assests/) \
> >(USERNAME=user1; cd ~user1/tmp && tar xopf -) \
> >(USERNAME=user2; cd ~user2/html-stuff && tar xopf -)
That makes use of two zsh
-specific features:
- setting
$USERNAME
changes the shell process EUID, UID, GID, EGID and supplementary gids to that of the user as per the user database (as if the user had logged in with that username). Note that if the user doesn't exist in the database, that will be silently ignored byUSERNAME=username
, butcd ~username
would then fail and cause the subshell to exit. - Redirecting a fd several times for output (here stdout, to two different process substitutions) triggers a
tee
like behaviour to send the output to the two targets (enabled with themult_ios
option, on by default). That saves reading the source twice.
Note that if any of the unpacking tar
processes dies, that will likely interrupt the whole pipeline.
ksh
or bash
don't have that change-user features, but you could use su
or sudo
instead if available, and tee
in place of the multios
feature:
(cd tmp/ftp && tar cf - new-assests/) |
tee >(cd ~user1/tmp && sudo -u user1 tar xopf -) |
(cd ~user2/html-stuff && sudo -u user2 tar xopf -)
That assumes the target user has write permission to the target directory.
Some tar
implementations have a --owner
/--group
or -chown
/-chgrp
options to override the user and group names of files stored in an archive. So another option would be to do something like:
(cd tmp/foo && tar --owner=user1 --group="$(id -g user1)" -cf - new-assets) |
(cd ~user1/tmp && tar xpf -)
And repeat for user2
.
In any of those, you may want to consider what to do if the files have ACLs as there's no one size fits all solution there.
Using rsync
:
rsync -ai --chown=user1 tmp/ftp/new-assests/ ~user1/tmp/
This would copy the directory to the given location and at the same time change the ownership of the files to user1
, if permitted.
The general form of the argument to --chown
is USER:GROUP
, but you may also use just USER
to set a particular user as owner, as above, or just :GROUP
to set a particular group (the :
is not optional if you leave the user ID out).