Sudo creates an environment variable "SUDO_USER" that you can use to find out the user who logged in (actually who ran Sudo).
Assuming you Sudo to root (it is possible to use Sudo to access other users too), you can write a script to automate the following two steps.
cp source target
chown $SUDO_USER target
(This won't work if you sudo to a non root user since only root can give away files.)
Automating it will be a bit of work. If source is a single file and target is not a directory, then your work is done. I assume that you asked the question because the problem is only a real issue in more complex situations, eg when doing something like:
cp /path/source/some*files /path/target/directory/
A complex script to figure out what files and what directories are passed, which ones were pre-existing, which ones were actually overwritten, and to change the ownership of only the successfully copied files could be written.
This work has already been done. You can use cpio
- After sudo to root, use cpio to copy the files. cpio needs a list of the files to copy so it is a two step process. Below I use ls
to generate the list of files to copy.
ls /path/source/some*files | cpio -pdm --owner $SUDO_USER /path/target/directory/
The -pdm
means "Passthrough mode, Create directories as needed, Maintain file modification times"
--owner $SUDO_USER"
causes the specified user to own the files.
The final operand is the directory where cpio must store the files.
To learn more about cpio awesomeness, go to the CPIO manual page here
Doing this in a single sudo command is also possible. Assuming that your user have rights to access the files, use sudo only for the cpio portion, like this:
ls /path/source/some*files | cpio -pdm --owner $USER /path/target/directory/
In the above case I'm using $USER in stead of $SUDO_USER because it is evaluated before Sudo runs. Alternatively, if the user doesn't have access to list the files, put it in a wrapper script and use sudo to run the wrapper. This can become harder, but in the simplest case The wrapper takes two arguments, a source and a target.
This goes into the "cp_as_user" wrapper:
ls $1 | cpio -pdm --owner $SUDO_USER $2
Then use the wrapper like this:
sudo cp_as_user "/path/to/some*files" /path/to/target/directory
sudo cat /etc/foo.txt > ~/foo.txt
. Files tend to be only readable by root for a reason, so remember to keep that reason in mind when making copies readable by non-root users.