Is there a way to tell sudo to set my username as owner for the files created instead of root?
Solution 1
Use install
instead of cp
:
sudo install -o belmin /etc/foo.txt ~/foo.txt
Solution 2
With a POSIX-compatible cp
you can sudo cp -p foo bar
to preserve the following file metadata when copying:
- Access time
- Modification time
- User ID
- Group ID
- Mode
If you want to set a different user JennyD's solution is best.
Solution 3
If you do:
sudo cat /etc/foo.txt > ~/foo.txt
Then ~/foo.txt
will be open by the shell as you (so created with your credentials), and then sudo
will be executed with its stdout redirected to that.
In the end, the file will be owned by you.
That kind of approach also helps limiting the things done by root
. Here, root
only uses his privilege to open /etc/foo.txt
, it doesn't do the thing that is potentially harmful (open a file for writing, that could have bad consequences if ~/foo.txt
was a symlink for instance).
Solution 4
Using sudo
, you switch to another user. That's the whole point of the command. I assume you don't have any regular access to the first file, so you need to be another user (root
in this case) to gain access.
There's no way for sudo
itself to manage that, since all sudo
is doing is switching you to the other user to execute the command.
You will need to
- keep using two commands (or one compound command)
- find another command (such as install, seen in another answer)
- or write a script and execute that script via
sudo
.
Solution 5
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
Related videos on Youtube
Comments
-
Belmin Fernandez over 1 year
If I do a
sudo cp /etc/foo.txt ~/foo.txt
, the new file is created withroot
as the owner.Right now, I see no way around this other than using the last two commands (
ls
to clarify use-case):belmin@server1$ ls /etc/foo.txt > -rw------- 1 root root 3848 Mar 6 20:35 /etc/foo.txt > belmin@server1$ sudo cp /etc/foo.txt ~/foo.txt belmin@server1$ sudo chown belmin: $_
I would prefer:
- Doing it in one
sudo
command. - Not having to specify my current user (maybe using a variable?).
-
jw013 almost 10 years
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.
- Doing it in one
-
EightBitTony almost 10 yearsI presume the person running sudo doesn't own the original file, otherwise they wouldn't need to use sudo.
-
Jenny D almost 10 yearsThat only works when the original file is owned by the target user.
-
Belmin Fernandez almost 10 yearsWasn't aware of
install
. Thank you. -
l0b0 almost 10 years@EightBitTony You don't need
sudo
to copy a file you don't own. You just need read access, after all. -
EightBitTony almost 10 yearsYes, mistype on my part - but I assume the user ID in question can't read the file either, because they still wouldn't need sudo. So we have to assume the user ID intended to own the final file has no access to the original file. Either way, this isn't a sudo 'problem'. Your answer suggests preserving an owner that we have to assume isn't desired.
-
Brian Rasmussen almost 10 years@BelminFernandez: In order to accommodate your second preference:
sudo install -o "$USER" /etc/foo.txt ~/foo.txt
-
Jenny D almost 10 yearsIt's theoretically possible that the file is owned by the target user but is located in a directory which the target user doesn't have permission to enter. But it's not very likely :-)
-
Johan almost 10 yearsThis assumes the user can write to the target directory.