Bash – Create a file as a different user and group

bashchownpermissionssu

I have a bash script that has to rsync to download files writing them locally, and then needs to set the owner to apache, and the group to a particular user group (that apache is not a member of).

Is there a way to create those files with those ownerships as they're being written by the rsync process, without having to go through and change them after the fact using chmod? There are so many files that the time it takes to go through them later is prohibitive.

I have to do this for multiple user groups, so I shouldn't be adding apache to these groups, and certainly can't make all of them the default group.

In other words: is there a way root can create a file as user X and group Y when X is not a member of Y?

I've tried using runuser, but I'm unable to set the group (presumably because apache doesn't belong to the group).

I know you can use chmod to change permissions and add any user/group combination. What I'm asking is if there is a way to open a file for writing and use any user/group combo while creating it.

Attempt using sudo:

[root@centos7 tmp]# groups angelo
angelo : angelo wheel
[root@centos7 tmp]# groups apache
apache : apache
[root@centos7 tmp]# sudo -u angelo -g apache touch angelo-file
Sorry, user root is not allowed to execute '/bin/touch angelo-file' as angelo:apache on centos7
[root@centos7 tmp]# ls -ld angelo-file
ls: cannot access angelo-file: No such file or directory
[root@centos7 tmp]# sudo -u angelo -g angelo touch angelo-file
[root@centos7 tmp]# ls -ld angelo-file
-rw-r--r-- 1 angelo angelo 0 Nov 12 03:13 angelo-file

Best Answer

If you want to create a file as a specific user and group without using chown, you can use sudo and specify the user and group:

sudo -u \#49 -g \#58 touch /tmp/something

Note that the user you specify must have permission to write to the directory where you attempt this.


Or, you can start a shell as the current user, with the group set to something else:

sudo runuser "$USER" -g somegroup

I tried this on a Vagrant box with success:

[vagrant@localhost ~]$ sudo runuser "$USER" -g floppy
[vagrant@localhost ~]$ touch testfile
[vagrant@localhost ~]$ ls -l testfile
-rw-r--r--. 1 vagrant floppy 0 Nov  9 15:57 testfile
[vagrant@localhost ~]$ 

This is despite the "vagrant" user not being part of the "floppy" group.

Related Question