Is there a way to tell sudo to set my username as owner for the files created instead of root?

5,168

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

  1. keep using two commands (or one compound command)
  2. find another command (such as install, seen in another answer)
  3. 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

Share:
5,168

Related videos on Youtube

Belmin Fernandez
Author by

Belmin Fernandez

Learning and helping.

Updated on September 18, 2022

Comments

  • Belmin Fernandez
    Belmin Fernandez over 1 year

    If I do a sudo cp /etc/foo.txt ~/foo.txt, the new file is created with root 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:

    1. Doing it in one sudo command.
    2. Not having to specify my current user (maybe using a variable?).
    • jw013
      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.
  • EightBitTony
    EightBitTony almost 10 years
    I presume the person running sudo doesn't own the original file, otherwise they wouldn't need to use sudo.
  • Jenny D
    Jenny D almost 10 years
    That only works when the original file is owned by the target user.
  • Belmin Fernandez
    Belmin Fernandez almost 10 years
    Wasn't aware of install. Thank you.
  • l0b0
    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
    EightBitTony almost 10 years
    Yes, 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
    Brian Rasmussen almost 10 years
    @BelminFernandez: In order to accommodate your second preference: sudo install -o "$USER" /etc/foo.txt ~/foo.txt
  • Jenny D
    Jenny D almost 10 years
    It'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
    Johan almost 10 years
    This assumes the user can write to the target directory.